anomalyco / anomalyco/opencode
Subagent permission/error events leave external integrations no way to see root-session progress (pane misreported as blocked/needs-input while subagent runs)
@jlongster is already working on this.
Since Sep 1, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 7h 2m
- Merged PRs (30d)
- 384
Description
Description
Child-session events (permission.asked, question.asked, session.error) are broadcast on the global event bus with only the child's sessionID and parentID in the payload, while the parent session's own status keeps reporting busy (or goes silent) for the whole duration of a subagent run. External consumers therefore cannot distinguish "a subagent inside this root session hit a transient stream error / a rule-evaluated permission that resolves itself" from "this root session is actually waiting on the user", and there is no reliable signal on the root session telling them the subagent recovered or finished.
Concretely: the herdr integration plugin (installed via herdr integration install opencode) maps child-session permission.asked / question.asked / session.error to blocked for the pane. When a subagent starts and later hits a transient stream error (which opencode auto-retries), the pane goes red "blocked" and plays the notification sound, even though:
- the screen shows no permission/error UI at all (the subagent is streaming and editing files normally), and
- the root session status never reflected anything but
busy.
Observed on a real run: while a code-writer subagent ran for ~15 minutes, the pane stayed blocked the whole time with zero state changes, while opencode's log showed continuous subagent streaming (mode=subagent) and file edits; herdr agent explain --json reported visible_blocker: false. The same session's log later showed AI_APICallError: Cannot connect to API ... socket connection was closed unexpectedly on the subagent session, which matches the plugin's blocked trigger.
A controlled capture of the SSE event bus (GET /event) while a subagent ran shows the gap directly:
session.status ROOT {type: busy} <- last root event before the subagent starts
session.created SUB ses_... (parentID set)
session.status SUB {type: busy} xN
session.status SUB {type: idle}
session.idle SUB
session.status ROOT {type: busy} <- root only updates again after the subagent finished
No permission.* events were emitted for an auto-allowed call, and no root-session event marks "a subagent of mine started / is running / failed transiently / recovered".
Request: surface subagent lifecycle on the root session (e.g. root-visible session.status reflecting child progress, or task.* / child-session state events that integrations can use), so external integrations can avoid rendering a running subagent (or its auto-recovering stream errors) as "waiting for user input".
Plugins
herdr-agent-state.js (installed by herdr integration install opencode, v10) — its behavior is the symptom, but the underlying issue is on the opencode event model side: child-session session.error reaches plugins with no root-session context and no follow-up "recovered" event on the root session.
OpenCode version
1.18.25
Steps to reproduce
- Install the herdr integration for opencode (
herdr integration install opencode) and run opencode inside herdr (any opencode ≥1.18 with plugins). - Prompt the agent to dispatch a subagent that runs a few minutes (e.g. a code-writer subagent editing several files), or let a subagent hit a transient API stream error (it auto-retries).
- While the subagent runs normally (or during its automatic retry), the herdr pane shows red
blockedand plays the notification sound; no approval or error UI is visible in the TUI.herdr agent explain <pane> --jsonshows stateblockedwithvisible_blocker: false. - Equivalent without herdr: capture
GET /eventon the opencode server while dispatching a subagent (see event sequence above) — the root session emits nothing between subagent start and completion, while childsession.status/session.errorevents appear with only the childsessionID.
Screenshot and/or share link
Not applicable (state observed via herdr agent list / herdr agent explain; can provide on request).
Operating System
macOS 26.6 arm64
Terminal
Ghostty 1.3.1
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.