MoonshotAI / MoonshotAI/kimi-code
Read.line_offset: anyOf integer 参数在第三方模型下 100% 失败(同版本数字形态正常,附Windows + Qwen3.8-Flash 复现)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
What version of Kimi Code is running?
0.39.1
Which open platform/subscription were you using?
第三方 OpenAI 兼容 provider(非 Moonshot 官方订阅)。
Which model were you using?
Qwen3.8-Flash(复现失败的会话);对照成功的会话使用 moonshot-cn/kimi-k2.7-code-highspeed
What platform is your computer?
Microsoft Windows NT 10.0.19045.0 x64
What issue are you seeing?
Read 工具的 line_offset 参数完全不可用:只要模型把它序列化进工具调用,就必然被参数校验拒绝,报
Invalid args for tool "Read": /line_offset must be integer; /line_offset must be integer;
/line_offset must match a schema in anyOf
(isError: true)
根因是值以 JSON 字符串形式到达校验层("line_offset": "200"),而校验用的是 Ajv 且未开启类型强制。
同一个参数以 JSON 数字形式("line_offset": 1)发出时校验通过并正常返回了文件内容,所以不是读取
逻辑坏了,是工具参数层对数字/布尔的字符串形态零容忍。
在本项目 4 个会话的 wire.jsonl 里,模型发出的 line_offset 一共 19 处,全部是字符串形态,对应 18 条
Invalid args 失败记录(值包括 "0" "1" "95" "100" "140" "200" "230" "240" "300" "340" "370" "-100")。
另一个变体:当模型按 Read 描述里的措辞猜了分页参数名时,
Invalid args for tool "Read": must NOT have additional property 'offset'; must NOT have additional
property 'limit'; /line_offset must be integer; ...
What steps can reproduce the bug?
- 把会话指向一个会把标量序列化成字符串的模型(此处 Qwen3.8-Flash)。
- 让它读取某个文件的指定行区间,例如「读 src/views/person-profile/detail.vue 的 100-120 行」。
- 看到的不是文件内容,而是上面那条 Invalid args;重试时模型通常改为省略该参数,于是报错被反复触发。
不需要模型即可复现的后半段:给 Read 传引号包裹的整数 line_offset,必被拒;同值不带引号,必通过。
证据(本地 wire.jsonl 原文):
- 失败:session d9e376ca-9fc0-4f01-9558-711ad278e092(args 中 "line_offset":"200" 等 19 处)
"args":{"path":"src/views/person-profile/detail.vue","line_offset":"200"} - 成功对照:session 429e6000-0c25-48cd-a13b-2aca43d8a900 / agents/agent-0 / wire.jsonl 第 124 行
"args":{"path":"AGENTS.md","line_offset":1,"n_lines":50}
→ tool.result 正常返回 "1\t# AGENTS.md — bgigc-party-monolithic-server"
可用 kimi export 导出 ZIP 作为附件。
What is the expected behavior?
line_offset 传 "200" 与传 200 应等价:合法的行号不应因为 JSON 序列化时多了引号就被拒绝。工具参数校验
应当容忍数字/布尔的字符串形态,而不是把原始 schema 报错回灌给模型、白白消耗一轮重试。
Additional information
一、这不是升级能解决的问题。0.39.1 就是发布通道里的最新版(CDN manifest latest=0.39.1,2026-08-28 发布),
且 line_offset 本身工作正常 —— 只是对第三方模型的输出形态不宽容。
二、CLI 内实际 schema(从 kimi.exe 打包产物中提取):
TailLineOffsetSchema = number().int().min(-MAX_LINES).max(-1)
PositiveLineOffsetSchema = number().int().min(1)
line_offset: union([PositiveLineOffsetSchema, TailLineOffsetSchema]).optional()
即暴露给模型的 JSON Schema 是 anyOf 两个 integer 分支。报错文本的措辞(must be integer / must match a
schema in anyOf)与打包产物里存在的 formatAjvErrors(...) 一致,说明工具参数由 Ajv 校验且 coerceTypes 关闭。
三、复合 anyOf 正是诱发点,而非「数字参数普遍有问题」。同批会话中所有简单 integer 参数一律通过:
Read.n_lines、Grep.head_limit、Grep.offset(含 head_limit: 2、offset: 0)。只有 line_offset 这个 anyOf
字段 100% 失败。另注:Read 的对外描述写的是 "Page larger files with line_offset",但工具并未暴露任何
分页别名,模型猜 offset/limit/line_start 会被 additionalProperties 直接拒。
四、建议修法(1 与 3 互补,不冲突):
- 校验工具参数时对 number/integer/boolean 开启 coerceTypes,或先用声明的 schema 归一化再校验;
unknown property 保持严格,以免掩盖真正的拼写错误。 - 校验失败时先做一次归一化重试,而不是把裸 schema 报错回灌给模型。
- 把单个标量写成 two-range union 的必要性去掉:摊平成一个 integer(minimum:-1000)加运行时
refine 拒绝 0。复合 anyOf 会显著抬高模型的字符串化概率。
Contribution
- I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the quoted and unquoted line_offset cases from the referenced wire.jsonl records, then locate the CLI's Ajv validation path, formatAjvErrors(...), and the Read schema containing the two integer branches. Compare normalization and unknown-property handling; done means stringified numeric and boolean scalars are handled as intended without accepting invalid property names, with regression coverage for line_offset.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100