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
Failed parallel tool call leaves dangling tool_call_id, causing 400 errors on all subsequent requests #44852
When a batch of parallel tool calls contains a failing tool (e.g. an MCP server returning 403), opencode does not write a tool-result message for the failed tool's tool_call_id. The session history then contains an assistant message with tool_calls that has no corresponding role:"tool" response, which violates the OpenAI chat-completions protocol.
Every subsequent request in that session replays the malformed message array and is rejected by protocol-strict providers with HTTP 400. Automatic retries cannot recover because they resend the same broken history.
Error message
400 BadRequestError
Invalid request: an assistant message with 'tool_calls' must be followed by tool messages
responding to each 'tool_call_id'.
The following tool_call_ids did not have response messages:
zammad_nube_zammad_get_article_attachments:2
(Observed against a vLLM-hosted model, Kimi-K3 via LiteLLM proxy. The vLLM behavior is correct per the OpenAI spec — the client is sending an invalid messages array.)
Reproduction
Configure an MCP tool that fails (e.g. returns 403 / auth error) alongside a working tool.
Prompt the model so it issues parallel tool calls including both tools.
One tool call fails (in my case another parallel call litellm_admin_litellm_model_list returned 403 and interrupted result flushing; the sibling call zammad_nube_zammad_get_article_attachments:2 never got a result message).
Continue the conversation. Every following request fails with the 400 above; retries (3x) all fail identically. Recovery only happens after the conversation history is rebuilt.
Expected behavior
Tool result flushing should be all-or-nothing per batch: even a failed tool call must produce a tool-result message, e.g. {"error": "403 Auth failed: ..."} — models handle error-text results gracefully.
If a tool call is aborted/times out before producing a result, persist a status:"error" result part instead of nothing.
Defense-in-depth: when serializing session parts to provider messages, synthesize a placeholder tool message for any dangling tool_call_id so old/affected sessions cannot poison future requests.
Confirmed still present on the latest release, v2.0.21 (reproduced 2026-10-01; v2.0.21 is the newest v2 tag).
Additional trigger, possibly distinct from the original MCP-403 case: the tool call was aborted because the command it ran restarted the managed background service (opencode service unset env <VAR>). On resume, a new step was dispatched before the aborted call's result was paired, so the request carried an assistant message with tool_calls and no matching tool message. Sessions without an interruption never reproduced it. Filed with the local evidence as #52452.
For reference, the failure is the strict OpenAI-compatible 400:
An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. (insufficient tool messages following tool_calls message)
Lenient providers (including Anthropic) accept the same history.
Note that the closest other reports are no longer actionable trackers: #49911 was withdrawn by its author, #22808 was auto-closed as stale, and #21326 only fixed the Anthropic path back in April. As far as I can tell this issue is the only open one for the OpenAI-compatible signal, so please keep it open unless it is genuinely superseded.
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.
Activity
github-actions commentedon Aug 25, 2026
This issue might be a duplicate of existing issues. Please check:
nowzycc commentedon Oct 1, 2026
Confirmed still present on the latest release, v2.0.21 (reproduced 2026-10-01; v2.0.21 is the newest
v2tag).Additional trigger, possibly distinct from the original MCP-403 case: the tool call was aborted because the command it ran restarted the managed background service (
opencode service unset env <VAR>). On resume, a new step was dispatched before the aborted call's result was paired, so the request carried an assistant message withtool_callsand no matchingtoolmessage. Sessions without an interruption never reproduced it. Filed with the local evidence as #52452.For reference, the failure is the strict OpenAI-compatible 400:
Lenient providers (including Anthropic) accept the same history.
Note that the closest other reports are no longer actionable trackers: #49911 was withdrawn by its author, #22808 was auto-closed as stale, and #21326 only fixed the Anthropic path back in April. As far as I can tell this issue is the only open one for the OpenAI-compatible signal, so please keep it open unless it is genuinely superseded.
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊