You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] 400 "A parameter specified is not valid" with volcengine kimi-k2.7-code on tool-call continuation (regression from 2.7.42) #1571
Requests carrying assistant tool_calls + tool messages routed to Volcengine kimi-k2.7-code are rejected by the upstream with 400: A parameter specified is not valid. Plain conversations work; only tool-call continuation turns fail.
Reproduction
POST https://ark.cn-beijing.volces.com/api/coding/v3/chat/completions, model kimi-k2.7-code, with these assistant messages followed by a matching tool message:
assistant message
result
content=null + tool_calls
200
content="" + tool_calls
200
content=[{"type":"text","text":""}] + tool_calls
400 "A parameter specified is not valid"
Root cause: emptyAssistantContent() in src/adapters/openai-chat.ts (introduced in 2.12.0) returns an empty text array [{type:"text",text:""}] for Volcengine Ark providers when an assistant message has tool_calls but no text. Volcengine kimi-k2.7-code rejects that shape. 2.7.42 used an empty string "" on the same path, which every Ark model accepts. Verified that deepseek-v4-flash, deepseek-v4-pro, doubao-seed-2.1-turbo, glm-5.2, minimax-m3 and kimi-k2.6 all accept content="".
Version
2.12.0 (confirmed still present in 2.13.0)
Operating system
Windows 10 Home China 10.0.19045
Provider and model
volcengine / kimi-k2.7-code
Logs or error output
Provider error 400: A parameter specified in the request is not valid
Confirmed against current dev: this is a real path-scoping regression.
The existing #796 compatibility guard keys only on the Ark hostname, so it applies the inferred structured empty assistant content to both the pay-as-you-go Chat endpoint (/api/v3) and the Coding Plan endpoint (/api/coding/v3). Your live matrix establishes that the Coding Plan contract is different: content: "" succeeds while [{"type":"text","text":""}] fails for kimi-k2.7-code.
I will narrow the quirk to the Ark endpoint family that originally required it, preserve the ordinary empty-string continuation on Coding Plan, and add regression coverage for both paths so a future host-wide cleanup cannot collapse them again. I will also record the endpoint-specific decision in the transport architecture notes. This will target dev; I will link the PR and validation results here after the patch is ready.
Exact head 52b1bef7e05aef23711e82cbbc672702943d3c2a keeps the structured placeholder only for the pay-as-you-go /api/v3 route and restores content: "" for /api/coding/v3. Focused regression coverage is 8/8, with typecheck and privacy scan green. I am leaving this issue open until independent exact-head CI/review and integration.
Fixed on dev in 9da50d0 (Merge pull request #1574).
Root cause: the #796 workaround matched only the Ark hostname, so it sent its structured empty assistant placeholder ([{"type":"text","text":""}]) to both endpoint contracts. Your evidence showed Coding Plan accepts content: "" and rejects the array form on a tool-call continuation. The placeholder is now scoped to recognized Ark hosts at the exact normalized /api/v3 path, so Coding Plan (/api/coding/v3) and unrelated paths keep the plain empty string.
Model IDs could not be used to identify the wire contract, since the same model is served on both plans — hence the path-based scoping.
Verification: tests/volcengine-ark-assistant-content.test.ts covers both endpoints; full suite on the merged dev is 11516 pass / 0 fail across 717 files with bun run typecheck clean.
#1570 was closed as a duplicate of this issue. Thanks for the precise repro — the empty-string vs empty-text-array contrast is what made this diagnosable.
Activity
Ingwannu commentedon Aug 13, 2026
Confirmed against current
dev: this is a real path-scoping regression.The existing #796 compatibility guard keys only on the Ark hostname, so it applies the inferred structured empty assistant content to both the pay-as-you-go Chat endpoint (
/api/v3) and the Coding Plan endpoint (/api/coding/v3). Your live matrix establishes that the Coding Plan contract is different:content: ""succeeds while[{"type":"text","text":""}]fails forkimi-k2.7-code.I will narrow the quirk to the Ark endpoint family that originally required it, preserve the ordinary empty-string continuation on Coding Plan, and add regression coverage for both paths so a future host-wide cleanup cannot collapse them again. I will also record the endpoint-specific decision in the transport architecture notes. This will target
dev; I will link the PR and validation results here after the patch is ready.Ingwannu commentedon Aug 13, 2026
The endpoint-scoped fix is now in draft PR #1574.
Exact head
52b1bef7e05aef23711e82cbbc672702943d3c2akeeps the structured placeholder only for the pay-as-you-go/api/v3route and restorescontent: ""for/api/coding/v3. Focused regression coverage is 8/8, with typecheck and privacy scan green. I am leaving this issue open until independent exact-head CI/review and integration.lidge-jun commentedon Aug 13, 2026
Fixed on
devin 9da50d0 (Merge pull request #1574).Root cause: the #796 workaround matched only the Ark hostname, so it sent its structured empty assistant placeholder (
[{"type":"text","text":""}]) to both endpoint contracts. Your evidence showed Coding Plan acceptscontent: ""and rejects the array form on a tool-call continuation. The placeholder is now scoped to recognized Ark hosts at the exact normalized/api/v3path, so Coding Plan (/api/coding/v3) and unrelated paths keep the plain empty string.Model IDs could not be used to identify the wire contract, since the same model is served on both plans — hence the path-based scoping.
Verification:
tests/volcengine-ark-assistant-content.test.tscovers both endpoints; full suite on the mergeddevis 11516 pass / 0 fail across 717 files withbun run typecheckclean.#1570 was closed as a duplicate of this issue. Thanks for the precise repro — the empty-string vs empty-text-array contrast is what made this diagnosable.