Annotation hit-history pager never ends for limit=0: has_more is computed from a page size the query does not use
还没有人认领这个 Issue。
评估
调研方向
从 GET /console/api/apps/{app_id}/annotations/{annotation_id}/hit-histories 的命中历史路由开始,检查它如何调用 libs/pagination.paginate_query。将 handler 的 page 和 limit 值与 pagination 实际使用的值进行比较,然后检查 AnnotationApi.get 和 AnnotationListApi.get 中相关的重新计算。完成标准是:无效的边界值不会导致无限的 has_more 响应,并且返回的 page 和 limit 与 query 匹配。
由索引模型根据 Issue 内容生成。
描述
Self Checks
- I have searched for existing issues, and this has not been reported before
- I am using the latest
main
Dify version
main at a4d74f7c
Cloud or Self Hosted
Self Hosted (Source)
Steps to reproduce
GET /console/api/apps/{app_id}/annotations/{annotation_id}/hit-histories?limit=0
That route reads both pagination parameters straight off the query string with no bounds:
page = request.args.get("page", default=1, type=int)
limit = request.args.get("limit", default=20, type=int)
effective_limit = min(limit, 100)
min(limit, 100) has no lower bound, but libs/pagination.paginate_query floors both at 1 before it runs the query:
page = max(1, page)
per_page = max(1, per_page)
So the query is served with a page size of 1 while the response reports limit: 0, and has_more is computed from the requested value:
has_more=page * effective_limit < total
page * 0 < total is true for every page, so a client that walks pages until has_more is false never stops. Past the end it keeps receiving empty pages that still claim there is more. limit=-1 behaves the same way.
Driving the real paginate_query against a seven-row table, with the handler's own arithmetic:
--- client asks limit=0, walks pages until has_more is false ---
page=1 rows=1 ids=[1] has_more=True (paginate_query.has_next=True)
...
page=7 rows=1 ids=[7] has_more=True (paginate_query.has_next=False)
page=8 rows=0 ids=[] has_more=True (paginate_query.has_next=False)
page=9 rows=0 ids=[] has_more=True
page=10 rows=0 ids=[] has_more=True
-> client never stopped after 10 pages
--- the same walk with limit=3 ---
page=3 rows=1 ids=[7] has_more=False -> client stops here
PaginatedResult.has_next is right in every one of those rows; it is the handler's separate recomputation from unclamped inputs that is not.
page has the same gap on this route: ?page=0 is served as page 1 while the response echoes page: 0.
The annotation list routes (AnnotationApi.get, service API AnnotationListApi.get) carry the same recomputation, introduced together with it in #41876. Those are currently protected because their query models declare limit: int = Field(default=20, ge=1), so only the hit-history route is reachable today.
✔️ Expected Behavior
has_more is false once the last page has been served, and limit/page in the response are the values the query actually used.
❌ Actual Behavior
has_more stays true forever for limit=0 or limit=-1, and the response reports a page size that was not used.
- 主要语言
- TypeScript
- 星标
- 157k
- 派生
- 24.7k
- 平均合并
- 22 小时 32 分钟
- 30 天内合并 PR
- 611
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
langgenius/dify 的其他 Issue
-
Annotation Reply: a stored score threshold of 0.0 is silently replaced with 1, disabling the feature 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
langgenius/dify#42639 · 1 条评论 · 1 个 reaction ·
-
难度 2/5 1-3 小时 新手友好度 70/100
langgenius/dify#42468 · 1 条评论 · 1 个 reaction ·
-
🐞 bug
难度 2/5 1-3 小时 新手友好度 86/100
langgenius/dify#42446 · 1 个 reaction ·
-
难度 2/5 1-3 小时 新手友好度 88/100
langgenius/dify#42355 · 1 条评论 · 1 个 reaction ·
-
难度 2/5 1-3 小时 新手友好度 88/100
langgenius/dify#42350 · 1 条评论 · 1 个 reaction ·
相似的 Issue
-
calcite-components needs triage refactor
难度 2/5 1-3 小时 新手友好度 75/100
Esri/calcite-design-system#15203 ·
-
难度 2/5 1-3 小时 新手友好度 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
难度 1/5 1 小时以内 新手友好度 95/100
-
难度 2/5 1-3 小时 新手友好度 78/100
Automattic/studio#4908 ·
-
难度 2/5 1-3 小时 新手友好度 90/100