anomalyco / anomalyco/opencode
Running subagent task is not navigable with fast tool-call providers
@rekram1-node is already working on this.
Since Aug 7, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
Running subagent tasks can become non-navigable when a custom LanguageModelV3 provider emits a complete client-side tool-call followed immediately by finish with reason tool-calls.
The task tool successfully creates the child session and runs the subagent, but clicking the task row does nothing while it is running. The session.child.first keybinding also does not enter the child session at that point. Other providers used in the same environment do not consistently reproduce the problem, while this provider timing reproduces it reliably.
This appears to be the metadata race previously reported in #20184. The tool execution calls ctx.metadata() with sessionId, but the processor can subsequently replace the pending state with a fresh running state before preserving that metadata. The TUI depends on state.metadata.sessionId to hydrate and navigate to the child session.
OpenCode version
1.18.10
I also inspected the 1.18.15 packages/opencode/src/session/processor.ts source. The previously proposed synchronous metadata buffering from #20210 does not appear to be present.
Steps to reproduce
- Use a custom LanguageModelV3 provider that returns a complete client-side
tasktool call without streamingtool-input-start/tool-input-delta/tool-input-end. - The provider emits
tool-call, then immediately emitsfinishwithunified: "tool-calls", and closes the public model stream. - Ask the model to launch a subagent that runs long enough to observe it.
- While the task row is running, click it or invoke
session.child.first.
Actual behavior
Nothing happens. The running subagent session cannot be opened from the parent session.
Expected behavior
The task row and session.child.first should navigate to the child session as soon as the native task tool creates it and publishes metadata.sessionId.
Diagnostic evidence
After the task completes, exporting the parent session shows that the task part has valid metadata:
{
"tool": "task",
"state": {
"status": "completed",
"metadata": {
"parentSessionId": "<parent-session>",
"sessionId": "<child-session>",
"model": {
"providerID": "kiro",
"modelID": "gpt-5.6-sol"
}
}
}
}
Exporting the referenced child session succeeds and shows its parent ID plus the complete subagent message history. Therefore the child is created correctly; only live navigation/hydration fails.
Suspected cause
There is a race between detached client tool execution and processing the provider tool-call event:
- Native
task.execute()starts and callsctx.metadata({ metadata: { sessionId } }). - The processor handles the provider
tool-calland transitions the part from pending to running. - That transition can replace the state without the metadata written in step 1.
- The TUI sees no
state.metadata.sessionId, so its click handler is a no-op and the child is not available to session-tree navigation.
The provider emits a valid complete tool call; manufacturing incremental tool-input events would only be a timing workaround and would not eliminate the race.
Related work
- #20184 reported the same pending-to-running metadata race.
- #20210 proposed synchronously buffering and merging tool metadata, with an E2E regression test, but was closed without merge.
- #14424 reported non-interactive Explore tasks with zero live tool calls.
- #32773 covered loss of
sessionIdmetadata during task completion/post-processing.
A robust fix should preserve or synchronously buffer tool metadata across pending-to-running transitions, independent of provider event timing.
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.
Assessment
This issue has not been assessed yet.