快速结论:该报错通常出现在调用 RAGFlow 的模型目录分页接口(GET /api/v1/models/all-models 或其管理端副本 GET /api/v1/admin/all-models)并传入 page/page_size 参数时,分页切片上界未按实际长度裁剪,且页码按 0 起始偏移处理。优先排查:请求页码是否从 1 开始、是否落在最后一页跨越末尾的位置,以及服务端是否已包含对应修复。
适用环境:Issue 讨论中确认的对象为 RAGFlow 后端(Go 实现,涉及 internal/service/model_service.go、internal/admin/service.go、internal/cli/cli.go、internal/common),模型目录规模在测试探针中为 len=3846 cap=4095。Issue 未提供操作系统、Python、CUDA、显卡或依赖版本信息,此处不作补充。
最快修复方案:升级到已合并 #22036 与 #22059 的版本;修复后 ListAllModels 经由 common.ValidatePagination 校验分页参数,并用 min(start+pageSize, len(models)) 裁剪切片上界。
注意事项:客户端若按 0 起始页码约定传 page,在修复版本上需改为 1 起始;不传 page 时行为为返回第一页。修复对应的测试分布在 ./internal/common/、./internal/service/、./internal/admin/、./internal/handler/、./internal/cli/,若自行打补丁需同步覆盖这些包。
问题场景
用户在 RAGFlow 中通过 CLI 或直接请求 REST 接口列出全部模型,并带有 page 与 page_size 分页参数。触发场景有三类:一是请求的页窗口跨越模型目录末尾(page*pageSize < len(models) < (page+1)*pageSize);二是模型切片容量紧凑,同一表达式直接 panic;三是按 CLI 文档以 1 起始传 page=1,但服务端以 0 起始偏移处理,导致第一页不可达。
报错原文
[Bug]: GET /api/v1/models/all-models returns null rows or panics when a page straddles the end, and page=1 skips the first page
slice bounds out of range
len=3846 cap=4095
page 128 size 30 -> 30 items, 24 nil
page 1 returned 10 models starting at aion-labs/aion-1.0-mini, want 302..aion-labs/aion-1.0
原因分析
最可能的原因:ModelProviderService.ListAllModels 与其管理端重复实现中的分页逻辑只校验了下界,未将上界限制为 len(models):
if pageSize > 0 && pageIndex >= 0 && pageIndex*pageSize < len(models) {
return models[pageIndex*pageSize : (pageIndex+1)*pageSize], nil
}
return models, nil
Go 对切片的双下标表达式只按容量检查上界,因此当页窗口越过末尾但仍在容量内时,会读到数据之后的空位,返回若干 null 条目;容量紧凑时会因上界超出容量而 panic,请求表现为 500 或连接中断。此外 pageIndex 被直接当作 0 起始偏移,而 CLI 帮助文本声明该参数为 1 起始(“Page number (1-based)”),于是 page=1 实际返回第二页。当 page*pageSize >= len(models) 时该分支被跳过,处理器返回完整目录,越界页因此静默忽略分页。
环境排查
- 确认 RAGFlow 版本是否已包含 #22036 与 #22059 的合并内容,尤其检查
internal/service/model_service.go、internal/admin/service.go中的分页表达式。 - 确认调用方(CLI 或自建脚本)使用的
page是 1 起始还是 0 起始。 - 确认请求中是否同时携带
page与page_size;缺省或page=0的语义是返回全部,不属于分页路径。 - 确认模型目录总条数与
page_size是否构成跨越末尾的页窗口,可用page*page_size与总条数比较判断。 - Issue 未说明操作系统、Python、CUDA、PyTorch、显卡或前端 WebUI 版本,这些项目与本问题无直接关联证据,无需作为排查前提。
解决步骤
- 升级到包含 #22036 与 #22059 的 RAGFlow 版本;这两个 PR 已将
ListAllModels改为统一走common.ValidatePagination。 - 确认修复后的切片上界为
min(start+pageSize, len(models)),即最后一页只返回剩余记录,跨越末尾的页不会再读到len之外的元素。 - 确认页码语义为 1 起始;若客户端此前按 0 起始传参,同步将首个请求页码调整为 1。
- 确认越界页(起始偏移大于等于总条数)返回空列表,而非整个目录、
null行或 panic。 - 如自行维护分支,可将原本位于 agent 列表接口的
slicePage辅助函数抽到internal/common,供服务端与管理端复用,避免两处重复的算术逻辑再次分叉。 - 可优先尝试:运行 Issue 中列出的包测试
./internal/common/、./internal/service/、./internal/admin/、./internal/handler/、./internal/cli/,其中新增用例覆盖容量紧凑切片不越界、第一页从首个模型开始、末页只返回余数、越界页为空。
验证方法
分别请求 page=1&page_size=N,确认返回结果从目录中的第一条模型开始而非第二条;请求最后一页,确认返回条数等于总条数除以 page_size 的余数,且响应中不含 null 行;请求起始偏移超过总条数的页,确认返回空列表而非完整目录或 500;对整个模型目录逐页遍历,确认各页记录不重叠、不缺失。
参考来源
infiniflow/ragflow #21727(修复 PR:#22036、#22059,已合并)
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: Wiki REFINE does not recover after transient LLM retries are exhausted](https://www.chat-gpts.plus/wp-content/uploads/2026/11/20929-0b02e3f8-768x403.jpg)
![[Bug]: Admin user list returns only the first 10 users when no page_size is given](https://www.chat-gpts.plus/wp-content/uploads/2026/11/21722-e4a3b681-768x403.jpg)
![[Bug]: Router retries and Retry-After sleeps ignore the caller's request timeout (x-litellm-timeout / x-stainless-timeout)](https://www.chat-gpts.plus/wp-content/uploads/2026/11/49751-63f458d7-768x403.jpg)