Skip to content

Bug: --page-all silently truncates data at default --page-limit=10 and falsely reports has_more=false #590

@xisheng687

Description

@xisheng687

Summary

lark-cli--page-all 模式在默认 --page-limit=10 下会静默截断数据,并且在输出里把 has_moretrue 改成 false,让下游调用方误以为已经取完全部分页。这会造成不可见的数据丢失,对"导出/同步/对账"类任务致命。

Environment

  • lark-cli version: 1.0.14
  • macOS 14
  • 命令:lark-cli wiki nodes list --page-all(子节点 ≈ 705 的 wiki 文件夹)

Reproduce

目标:列出某个 wiki 父节点下的全部子节点(实际有 705 个)。

# Default 行为(--page-limit 默认 10)
lark-cli wiki nodes list --params '{"space_id":"<sp>","parent_node_token":"<parent_with_705_children>"}' --page-all
# → items.length = 200
# → has_more: false    ← 错!实际上还有 505 条

# 加大 page-limit
lark-cli wiki nodes list --params '{"space_id":"<sp>","parent_node_token":"<parent_with_705_children>"}' --page-all --page-limit 20
# → items.length = 400
# → has_more: false    ← 仍然错!

# 唯一能拿全的写法
lark-cli wiki nodes list --params '{"space_id":"<sp>","parent_node_token":"<parent_with_705_children>"}' --page-all --page-limit 0
# → items.length = 705
# → has_more: false   ← 这次对

对比:用原生 API + 手动 page_token 分页,始终能拿到 705:

page_token = ""
while True:
    params = {"space_id": sp, "parent_node_token": parent, "page_size": 50}
    if page_token: params["page_token"] = page_token
    data = lark_cli("api GET /open-apis/wiki/v2/spaces/{sp}/nodes", params)
    items.extend(data["items"])
    if not data["has_more"]: break
    page_token = data["page_token"]
# → 705 items,has_more 的 true/false 真实反映状态

Why it's a bug

  1. 静默 data loss:default 配置下任何子节点 ≥200 的父节点都会丢数据,用户没有任何错误提示
  2. has_more=false 是假的:达到 --page-limit 上限时应该保留 has_more=true 让调用方知道还需翻页;现在强行改成 false 破坏 API 契约
  3. 文档没警示--page-limit 10 (default) 配合未文档化的 20/page 默认 page_size,上限就是 200 条 —— 大多数用户不会预料到
  4. 背景:wiki 知识库里单个父节点 700+ 子节点很常见(月度心得合集/月度归档/大系列文章),这在知识库治理场景里是日常

实际踩坑

在一次内容工厂全量同步任务里:

  • 原以为知识库总计 519 节点(lark-cli 扫的)
  • 同步到追踪表后只有 340 条
  • 用户反馈"我心得有 700+ 条怎么表里才 200"
  • 排查 2 小时才定位到 --page-all 截断的根因
  • 真实节点数是 1024,--page-all 漏了 505 条(49%)

Suggested fix

三选一或叠加:

A. 改默认--page-limit 默认从 10 改成 0(无限)。--page-all 的命名就应该意味着"all pages"
B. 诚实的 has_more:达到 page-limit 但 API 返回 has_more=true 时,输出保留 has_more=true 而不是改成 false,让调用方能检测到截断
C. stderr 警告:截断时在 stderr 打印 WARN: --page-limit reached (got N pages), data truncated. Use --page-limit 0 for all pages.

推荐 B+C 组合(不改默认避免 breaking,但让截断可观测)。

可能影响的其它命令

任何用 --page-all 的命令都有同样风险:

  • wiki nodes list ✓ 已验证
  • base +record-listdrive files listim +messages-list 等未验证但大概率同 bug(共用 --page-all 框架)

建议在 CI 里加"≥500 item 父节点"的回归测试。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain/basePR touches the base domaindomain/docDocs domaindomain/imPR touches the im domaindomain/wikiWiki domain

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions