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
parallel streamed tool calls with empty arguments {} hang in "Writing command" (shell) or "delegating" ("General Subagent - Subagent") #58481
When a model via litellm-proxy/gemini-4-argon emits multiple tool calls in one assistant turn (for example, shell + subagent or multiple subagent calls with escaped quotes), the streamed arguments can arrive at OpenCode as an empty object {} during or after tool-call stream assembly. This happens before permission evaluation and leaves tool calls stuck in "Writing command" or "delegating" with {} arguments. Instead of immediately failing schema validation (required: ["agent", "description", "prompt"]) and returning a tool error to the model so it can retry, OpenCode may fall back to display defaults ("General Subagent - Subagent").
Plugins
No response
OpenCode version
2.1.2
Steps to reproduce
Configure a provider using litellm-proxy with a Gemini model (gemini-4-argon).
Prompt the agent to emit multiple tool calls in one assistant turn, such as shell + subagent or multiple subagent calls with escaped quotes in their prompts.
Observe that this happens before permission evaluation, during or after tool-call stream assembly; the serialized arguments may be {} (for example, [Assistant tool call]: subagent({})).
Observe the TUI: tool calls remain stuck in "Writing command" or delegating with labels such as General Subagent - Subagent, until manually interrupted.
Expected Behavior
If a subagent tool call finishes streaming with missing required fields (agent, description, prompt — e.g. {}), OpenCode should immediately reject the tool call with a validation error (e.g. Invalid arguments for tool "subagent": missing required fields "agent", "description", "prompt") rather than attempting to spawn/delegate to a fallback "general" subagent or hanging in "delegating".
Actual Behavior
The UI displays General Subagent - Subagent waiting in delegating indefinitely, requiring manual user interruption (Esc / cancel).
Workarounds found
Adding an explicit {"action": "subagent", "resource": "*", "effect": "deny"} + allowlist for named subagents in opencode.json.
Instructing the model in AGENTS.md to emit at most 1 subagent call per turn, never combine subagent with other tool calls in the same turn, and avoid escaped quotes or code fences inside subagent prompts.
Thanks for the report. I couldn't reproduce the hang on 2.1.2. I set up an OpenAI-compatible provider pointing at a mock server that streams a shell call and a subagent call in one assistant turn (with escaped quotes in the prompt), and tried several ways of streaming them:
Both calls in one chunk (index 0 and 1), or with no index: both ran and completed.
Separate chunks that both use index: 0 with different ids: the second call's arguments were appended to the first. The subagent call was lost, and the first call showed {} and failed straight away with a JSON parse error, which went back to the model. That may be where your {} comes from, but it didn't hang.
The stream ending without a finish_reason: the call failed straight away with "stream ended without finish_reason".
In every case the tool calls settled within a second. None stayed in "Writing command" or "delegating". Related issues, most likely first:
A raw capture of the streaming response LiteLLM sends for one of these turns (the data: chunks with tool_calls), especially the index, id and finish_reason fields, and whether the stream actually ends.
The OpenCode logs from such a session (e.g. run with --print-logs --log-level debug).
Closing this for now, since we haven't heard back. I couldn't reproduce the hang on 2.1.2. With a mock LiteLLM-style server streaming parallel shell + subagent calls, every tool call settled within a second: it either ran or failed straight away with an error the model could see. None stayed stuck in "Writing command" or "delegating". Without a capture of what LiteLLM actually streams, there's no clear way to dig further.
If it still happens, please reopen or comment here with:
the raw data: chunks LiteLLM sends for such a turn (especially index, id, finish_reason, and whether the stream ends);
logs from --print-logs --log-level debug;
your LiteLLM version.
A stream that stops partway through a tool call without ending is tracked in #51291, which may be the same problem. Thanks for the report!
Activity
opencode-agent commentedon Oct 23, 2026
Thanks for the report. I couldn't reproduce the hang on 2.1.2. I set up an OpenAI-compatible provider pointing at a mock server that streams a
shellcall and asubagentcall in one assistant turn (with escaped quotes in the prompt), and tried several ways of streaming them:index0 and 1), or with noindex: both ran and completed.index: 0with differentids: the second call's arguments were appended to the first. Thesubagentcall was lost, and the first call showed{}and failed straight away with a JSON parse error, which went back to the model. That may be where your{}comes from, but it didn't hang.finish_reason: the call failed straight away with "stream ended without finish_reason".In every case the tool calls settled within a second. None stayed in "Writing command" or "delegating". Related issues, most likely first:
{}) tool call stuck forever, which turned out to be the placeholder shown while a call is streaming. Closed as a duplicate of Provider stream can disappear while tool call remains permanently "running" with no timeout/reaper #51291.These would help:
data:chunks withtool_calls), especially theindex,idandfinish_reasonfields, and whether the stream actually ends.--print-logs --log-level debug).opencode-agent commentedon Oct 26, 2026
Closing this for now, since we haven't heard back. I couldn't reproduce the hang on 2.1.2. With a mock LiteLLM-style server streaming parallel
shell+subagentcalls, every tool call settled within a second: it either ran or failed straight away with an error the model could see. None stayed stuck in "Writing command" or "delegating". Without a capture of what LiteLLM actually streams, there's no clear way to dig further.If it still happens, please reopen or comment here with:
data:chunks LiteLLM sends for such a turn (especiallyindex,id,finish_reason, and whether the stream ends);--print-logs --log-level debug;A stream that stops partway through a tool call without ending is tracked in #51291, which may be the same problem. Thanks for the report!