Bug Description
Subagents (explore, general) can invoke the Task tool to spawn child subagents, which in turn spawn their own children, with no recursion depth limit. This leads to runaway nesting that wastes tokens and creates dozens of useless intermediate sessions.
Reproduction
- Use
claude-opus-4.6 (GitHub Copilot) as the model
- In a session, trigger a complex investigation that causes the primary agent to dispatch an
explore subagent with a detailed prompt (e.g. "very thorough exploration of [repo] to answer [complex question]")
- The
explore subagent, instead of using its own Read/Grep/Glob tools directly, dispatches another explore subagent via Task with nearly the same prompt
- That child does the same thing, creating an infinite recursion chain
Observed Behavior
In my session, this produced:
- 47 total sessions (1 parent + 46 nested child/grandchild sessions)
- 20 levels of nesting depth
- 18 layers of pure explore→explore recursion (depth 2 through 19), each doing nothing except re-dispatching the same task to another explore agent
- Only the deepest agent (depth 19) actually performed real work (grep, read files)
Session tree (abbreviated):
depth 0: "OpenCode的一个BUG" (build, primary) depth 1: 8 subagent sessions (general + explore) depth 2: "Search thinking_budget and reasoning stripping" (explore) depth 3: "Explore thinking/reasoning stripping" (explore) depth 4: "Thorough exploration of reasoning stripping" (explore) depth 5: "Explore reasoning stripping logic" (explore) ... (same pattern continues) depth 19: "Explore opencode reasoning stripping" (explore) ← finally does actual work here depth 20: 4x general subagents (read files)
Each intermediate explore agent (depth 2–18) follows the exact same pattern:
- Receives prompt
- Outputs: "I'll launch a very thorough exploration..."
- Dispatches another explore subagent with the same prompt via Task
- Child gets aborted or repeats
Root Cause
Two contributing factors:
-
Model behavior: The LLM re-delegates its own task to an identical subagent instead of using its available tools directly. This is a known LLM tendency — the model interprets "thorough exploration" as requiring delegation rather than direct action.
-
Framework gap: OpenCode has no recursion depth guard on the Task tool. A subagent at any depth can spawn further subagents without limit. There is no max_depth parameter or built-in circuit breaker.
Expected Behavior
OpenCode should enforce a maximum nesting depth for subagent Task invocations. Suggested default: 3 levels. When the limit is reached, the Task tool should either:
- Return an error message telling the agent to perform the work directly
- Or simply be unavailable (removed from the tool list)
Workaround
Until a framework-level fix is available, users can mitigate this via opencode.jsonc agent config:
jsonc "agent": { "general": { "prompt": "CRITICAL ANTI-RECURSION RULE: You are a subagent. NEVER use the Task tool to dispatch another subagent for the same task you were given. If you need to explore code, use Read/Grep/Glob/Bash directly. Only use Task to dispatch a DIFFERENT type of agent (e.g. general dispatching explore) for a genuinely independent subtask — never to re-delegate your own work. Maximum nesting depth is 1.", "steps": 30 }, "explore": { "prompt": "CRITICAL ANTI-RECURSION RULE: You are a subagent. NEVER use the Task tool to dispatch another subagent. You have direct access to Read, Grep, Glob, and Bash tools — use them yourself. Do NOT delegate your work to another agent.", "permission": { "task": { "*": "deny" } }, "steps": 20 } }
Key points:
explore: Deny Task permission entirely (it's a read-only agent that should never need to spawn children)
general: Keep Task permission but add anti-recursion prompt instructions + steps limit as a safety net
steps: Hard cap on iterations — even if the prompt instruction is ignored, it won't run forever
Environment
- OpenCode v1.2.16
- Model:
claude-opus-4.6 via GitHub Copilot
- Platform: Windows 11 (pwsh 7)
Bug Description
Subagents (
explore,general) can invoke the Task tool to spawn child subagents, which in turn spawn their own children, with no recursion depth limit. This leads to runaway nesting that wastes tokens and creates dozens of useless intermediate sessions.Reproduction
claude-opus-4.6(GitHub Copilot) as the modelexploresubagent with a detailed prompt (e.g. "very thorough exploration of [repo] to answer [complex question]")exploresubagent, instead of using its own Read/Grep/Glob tools directly, dispatches anotherexploresubagent via Task with nearly the same promptObserved Behavior
In my session, this produced:
Session tree (abbreviated):
depth 0: "OpenCode的一个BUG" (build, primary) depth 1: 8 subagent sessions (general + explore) depth 2: "Search thinking_budget and reasoning stripping" (explore) depth 3: "Explore thinking/reasoning stripping" (explore) depth 4: "Thorough exploration of reasoning stripping" (explore) depth 5: "Explore reasoning stripping logic" (explore) ... (same pattern continues) depth 19: "Explore opencode reasoning stripping" (explore) ← finally does actual work here depth 20: 4x general subagents (read files)Each intermediate explore agent (depth 2–18) follows the exact same pattern:
Root Cause
Two contributing factors:
Model behavior: The LLM re-delegates its own task to an identical subagent instead of using its available tools directly. This is a known LLM tendency — the model interprets "thorough exploration" as requiring delegation rather than direct action.
Framework gap: OpenCode has no recursion depth guard on the Task tool. A subagent at any depth can spawn further subagents without limit. There is no
max_depthparameter or built-in circuit breaker.Expected Behavior
OpenCode should enforce a maximum nesting depth for subagent Task invocations. Suggested default: 3 levels. When the limit is reached, the Task tool should either:
Workaround
Until a framework-level fix is available, users can mitigate this via
opencode.jsoncagent config:jsonc "agent": { "general": { "prompt": "CRITICAL ANTI-RECURSION RULE: You are a subagent. NEVER use the Task tool to dispatch another subagent for the same task you were given. If you need to explore code, use Read/Grep/Glob/Bash directly. Only use Task to dispatch a DIFFERENT type of agent (e.g. general dispatching explore) for a genuinely independent subtask — never to re-delegate your own work. Maximum nesting depth is 1.", "steps": 30 }, "explore": { "prompt": "CRITICAL ANTI-RECURSION RULE: You are a subagent. NEVER use the Task tool to dispatch another subagent. You have direct access to Read, Grep, Glob, and Bash tools — use them yourself. Do NOT delegate your work to another agent.", "permission": { "task": { "*": "deny" } }, "steps": 20 } }Key points:
explore: Deny Task permission entirely (it's a read-only agent that should never need to spawn children)general: Keep Task permission but add anti-recursion prompt instructions +stepslimit as a safety netsteps: Hard cap on iterations — even if the prompt instruction is ignored, it won't run foreverEnvironment
claude-opus-4.6via GitHub Copilot