Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions packages/web/src/content/docs/agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,45 @@ Rules are evaluated in order, and the **last matching rule wins**. In the exampl
Users can always invoke any subagent directly via the `@` autocomplete menu, even if the agent's task permissions would deny it.
:::

:::caution[Recursive subagent nesting]
Setting `permission.task` rules **globally** (in the top-level `permission` block) or directly on a subagent definition enables that subagent to spawn further subagents. OpenCode has **no depth limit** on this recursion.

Each child session runs independently with its own `steps` counter and context window. If subagents recursively spawn more subagents, token usage grows exponentially — 10 levels of binary branching creates over 2,000 independent sessions, each consuming API tokens.

Neither `steps` nor `doom_loop` protect against this. `steps` limits iterations per session (each child gets its own counter), and `doom_loop` detects repeated calls within a single session, not across parent-child sessions.

**Safe pattern** — set `permission.task` only on primary agents, targeting specific subagents:

```json title="opencode.json"
{
"agent": {
"orchestrator": {
"mode": "primary",
"permission": {
"task": {
"*": "deny",
"explore": "allow",
"general": "allow"
}
}
}
}
}
```

**Unsafe pattern** — global `task` permission enables all agents (including subagents) to spawn recursively:

```json title="opencode.json"
{
"permission": {
"task": "allow"
}
}
```

You do **not** need an explicit `"task"` permission for primary agents to spawn subagents — the default `"*": "allow"` already covers this. Adding an explicit `"task": "allow"` globally is what overrides the built-in nesting guard.
:::

---

### Color
Expand Down
4 changes: 4 additions & 0 deletions packages/web/src/content/docs/config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,10 @@ For example, to ensure that the `edit` and `bash` tools require user approval:
}
```

:::caution
Be cautious with `"task": "allow"` in the global permission block. Unlike other permissions, this enables subagents to spawn further subagents recursively with no depth limit. See [Agents — Recursive subagent nesting](/docs/agents#recursive-subagent-nesting).
:::

[Learn more about permissions here](/docs/permissions).

---
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/content/docs/permissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ OpenCode permissions are keyed by tool name, plus a couple of safety guards:
- `grep` — content search (matches the regex pattern)
- `list` — listing files in a directory (matches the directory path)
- `bash` — running shell commands (matches parsed commands like `git status --porcelain`)
- `task` — launching subagents (matches the subagent type)
- `task` — launching subagents (matches the subagent type). See [Agents — Recursive subagent nesting](/docs/agents#recursive-subagent-nesting) for important caveats when setting this globally.
- `skill` — loading a skill (matches the skill name)
- `lsp` — running LSP queries (currently non-granular)
- `todoread`, `todowrite` — reading/updating the todo list
Expand Down
Loading