Skip to content

fix: 知识库文件列举在固定偏移段稳定 400(objectKey 不能为空),整页连带失败 #2545

Open

Description

@jackyfan01

Pre-submission checklist | 提交前检查

  • I have searched existing issues and this hasn't been mentioned before | 我已搜索现有问题,确认此问题尚未被提及
    (已搜 objectKey / 40085 / Memory ID does not exist / page_size knowledgebase 均无;
    [Feature Request] 知识库 List 接口 - list knowledgebases / list kb documents #1382 是「缺少列举接口」的功能请求且已关闭,本条是已有接口的数据缺陷,不是同一问题)
  • I have read the project documentation and confirmed this issue doesn't already exist | 我已阅读项目文档并确认此问题尚未存在
  • This issue is specific to MemOS and not a general software issue | 该问题是针对 MemOS 的,而不是一般软件问题

Bug Description | 问题描述

产品面:MemOS Cloud REST API(https://memos.memtensor.cn/api/openmem/v1),非开源包。

POST /get/knowledgebase-file 按 knowledgebase_id 分页列举知识库文件时,某个知识库中存在
连续 15 条记录(全局偏移 600–614)在任何 page_size 下都返回 HTTP 400:

{"code":40000,"data":null,"message":"Invalid request parameters: objectKey 不能为空"}

两个叠加的问题:

  1. 整页连带失败:只要页内含至少一条坏记录,整页 400 且不返回该页任何数据。因此实际丢失的记录数
    远多于 15 条,且随 page_size 线性放大:

    page_size 失败页 实际丢失记录数
    1 page 600–614 15(恰为坏行本身)
    10 page 60–62 30
    20 page 30–31 40
    50 page 12–13 100
    100 page 7 100
  2. total 不反映缺口:page_size=50 遍历全库,total 照报 1228,实收去重只有 1128(缺 100)。
    调用方只能靠「实收 ≠ total」自己发现缺口——我们此前多次误以为「遍历完成」。

期望行为:坏记录应被跳过并在响应里标注(或让 total 与实际可列举数一致),而不是让整页失败。

How to Reproduce | 如何重现

import json, urllib.error, urllib.request

BASE = "https://memos.memtensor.cn/api/openmem/v1"
KB = "base8a11251c-0cdc-4018-a722-930bc6b719f4"
API_KEY = "<your project api key>"

def call(page, size):
    req = urllib.request.Request(
        BASE + "/get/knowledgebase-file",
        data=json.dumps({"knowledgebase_id": KB, "page": page, "page_size": size}).encode(),
        method="POST",
        headers={"Content-Type": "application/json", "Authorization": "Token " + API_KEY})
    try:
        with urllib.request.urlopen(req, timeout=30) as r:
            return json.loads(r.read().decode())
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode()

# 1) 行级定位:page_size=1 逐偏移扫 585..626,只有 600..614 失败
for off in range(585, 627):
    r = call(off, 1)
    if not (isinstance(r, dict) and (r.get("data") or {}).get("file_detail_list")):
        print("bad offset", off, r)
# -> bad offset 600..614  HTTP 400 {"code":40000,...,"objectKey ..."}

# 2) 整页连带:同一批坏行,page_size=50 时第 12、13 页整页失败
print(call(12, 50))   # HTTP 400
print(call(13, 50))   # HTTP 400

# 3) total 与实收脱钩
got = set()
for p in range(1, 40):
    r = call(p, 50)
    if isinstance(r, dict):
        fl = (r.get("data") or {}).get("file_detail_list") or []
        got |= {f["id"] for f in fl}
        total = r["data"]["total"]
print("total =", total, " listable =", len(got))   # total = 1228  listable = 1128

重试情况:对失败页做 3 轮指数退避重试全部仍 400,与并发/限流无关。

Environment | 环境信息

  • Product surface: MemOS Cloud REST API openmem/v1(https://memos.memtensor.cn/api/openmem/v1)
  • Python version: 3.13(复现脚本仅用标准库 urllib)
  • Operating System: Windows 11
  • MemOS version: 不适用(云端 API 问题,未安装开源 memoryos 包)
  • 账户侧定位信息:user_id = Qoder,受影响知识库 base8a11251c-0cdc-4018-a722-930bc6b719f4

Additional Context | 其他信息

已排除的归因:不是解析失败记录的伴生现象。该库有 107 条 status=PROCESSING_FAILED,
全部位于偏移 ≥680;坏块 600–614 两侧最近的记录都是 status=AVAILABLE。所以
objectKey 不能为空 指向对象存储 key 缺失/悬挂,与解析状态无关。

邻近可列举锚点(只给 file_id,不公开文件名):

offset 595   status=AVAILABLE   file_id 82cbccc72edb154a7a159642898af714
offset 600-614  不可读(任何 page_size 下都取不到任何字段)
offset 616   status=AVAILABLE   file_id b9f449e44ace8d5f4d71f2bd29464e50

请协助确认:这 15 条记录在服务端内部的 file_id / objectKey 状态是什么?它们是否仍占用 total 计数?
是否可以在响应里返回「不可读记录数」,或让坏记录以占位条目形式返回而不是整页失败?

文档侧一处勘误(同端点):POST /get/file 这个端点并不存在(返回 HTTP 500 {"code":50000,"message":""}),
列举知识库文件的正式端点是 POST /get/knowledgebase-file;该页对 page_size 未标注上限,
也未说明「页内含坏记录时整页失败」这一行为,建议补充。

Willingness to Implement | 实现意愿

  • I'm willing to implement this myself | 我愿意自己解决
  • I would like someone else to implement this | 我希望其他人来解决
    (缺陷在服务端数据/对象存储侧,客户端无法修)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:coreMOS 编排层 / 框架底座 / 跨模块问题status:needs-triageNeeds initial triage | 需要初步判断 & 问题复现types:bugSomething isn't working | 功能异常

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions