Description
When the primary agent dispatches work to a sub-agent via the task tool, the sub-agent's session.id (task_id) is only returned on the success path. If the sub-agent crashes, times out, or is cancelled by the user, SessionPrompt.prompt() throws and the task_id is never communicated back to the calling agent.
This makes recovery impossible: the primary agent has no "handle" to reuse or inspect the failed sub-agent session.
Root Cause
In packages/opencode/src/tool/task.ts (≈ lines 128–162):
// No try-catch around this call:
const result = await SessionPrompt.prompt({
sessionID: session.id,
// ...
})
// task_id is only included in the SUCCESSFUL return:
const output = [
`task_id: ${session.id} (for resuming to continue this task if needed)`,
"",
"<task_result>",
text,
"</task_result>",
].join("\n")
return { title: params.description, metadata: { sessionId: session.id, model }, output }
If SessionPrompt.prompt() throws (cancellation, timeout, LLM error, etc.), the exception propagates without any session.id context. The primary agent receives a generic "Tool execution aborted" error with no way to reference or resume the sub-session.
Impact
No recovery: The LLM cannot call task with reuse: <task_id> because it never received the ID.
Wasted work & cost: All tokens/actions from the failed sub-agent are invisible and unreachable.
Related symptoms: Issues #9003, #6573, and the "Explore subagent hangs indefinitely" report all describe scenarios where the parent agent is stuck after a sub-agent failure — part of the reason recovery is impossible is this missing task_id.
Suggested Fix
Wrap the SessionPrompt.prompt() call in a try-catch and always return the session.id, even on error:
let result
try {
result = await SessionPrompt.prompt({
sessionID: session.id,
// ...
})
} catch (error) {
return {
title: params.description,
metadata: { sessionId: session.id, model },
output: [
`task_id: ${session.id} (sub-agent session preserved — reuse to retry/inspect)`,
"",
"<task_error>",
error instanceof Error ? error.message : String(error),
"</task_error>",
].join("\n"),
}
}
// ... existing success path ...
This ensures the primary agent always has a handle to the sub-session, regardless of outcome.
Environment
OpenCode version: 1.2.x (also affects 1.0.x and 1.1.x)
Affects all providers and models
Related Issues
#9003 — main agent hangs because of subagent (explore)
#6573 — Sessions hang indefinitely when Task tool spawns subagents via REST API
Plugins
No response
OpenCode version
1.2.0
Steps to reproduce
- Open a session with any model (e.g. Claude Opus 4.6) and send a prompt complex enough to trigger the task tool (e.g. "Explore the codebase and explain how authentication works").
- While the sub-agent is running, press Esc to cancel execution (or wait for it to hit a timeout / LLM error).
- Observe that the primary agent receives "Tool execution aborted" with no
task_id in the response.
- Ask the primary agent to retry or resume the sub-agent's work — it will acknowledge that it has no session handle to reuse:
"Eu não reutilizei a sessão anterior porque a tentativa terminou com Tool execution aborted e não retornou task_id. Sem task_id, o contrato me impede de reusar."
- Navigate to the sub-agent list in the TUI — the sub-agent session exists (it was persisted in the DB), and may even contain useful partial results, but the primary agent is permanently blind to it.
Screenshot and/or share link
No response
Operating System
Ubunu 24.04.4
Terminal
Ghostty 1.2.3
Description
When the primary agent dispatches work to a sub-agent via the task tool, the sub-agent's
session.id (task_id)is only returned on the success path. If the sub-agent crashes, times out, or is cancelled by the user,SessionPrompt.prompt()throws and thetask_idis never communicated back to the calling agent.This makes recovery impossible: the primary agent has no "handle" to reuse or inspect the failed sub-agent session.
Root Cause
In
packages/opencode/src/tool/task.ts (≈ lines 128–162):If
SessionPrompt.prompt()throws (cancellation, timeout, LLM error, etc.), the exception propagates without anysession.idcontext. The primary agent receives a generic "Tool execution aborted" error with no way to reference or resume the sub-session.Impact
No recovery: The LLM cannot call
taskwith reuse:<task_id>because it never received the ID.Wasted work & cost: All tokens/actions from the failed sub-agent are invisible and unreachable.
Related symptoms: Issues #9003, #6573, and the "Explore subagent hangs indefinitely" report all describe scenarios where the parent agent is stuck after a sub-agent failure — part of the reason recovery is impossible is this missing task_id.
Suggested Fix
Wrap the
SessionPrompt.prompt()call in a try-catch and always return thesession.id, even on error:This ensures the primary agent always has a handle to the sub-session, regardless of outcome.
Environment
OpenCode version: 1.2.x (also affects 1.0.x and 1.1.x)
Affects all providers and models
Related Issues
#9003 — main agent hangs because of subagent (explore)
#6573 — Sessions hang indefinitely when Task tool spawns subagents via REST API
Plugins
No response
OpenCode version
1.2.0
Steps to reproduce
task_idin the response."Eu não reutilizei a sessão anterior porque a tentativa terminou com Tool execution aborted e não retornou task_id. Sem task_id, o contrato me impede de reusar."Screenshot and/or share link
No response
Operating System
Ubunu 24.04.4
Terminal
Ghostty 1.2.3