[BUG] CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 does not disable nesting on 2.1.225; effective depth is one level greater than configured

Status Open
Reported on v2.1.225
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Aug 8, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 no longer disables nested subagent spawning. On 2.1.225 the effective limit sits one level higher than configured: a subagent still receives the Agent tool and still successfully spawns a nested subagent. Only the third level is a leaf.

The 2.1.219 changelog states the contract verbatim:

Subagents can now spawn nested subagents up to depth 3 by default (was 1); set CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 to disable nesting

Nesting is not disabled. It is capped at exactly one nested level.

This matters beyond convenience. The variable is the documented control for containing subagent fan-out, and "(was 1)" in that same line means depth 1 was the value that disabled nesting in 2.1.217/2.1.218. An operator who sets it to 1 to keep a flat spawn topology gets a two-level tree instead, silently, with no warning anywhere.

What Should Happen?

With CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1, a subagent spawned from the main session should not receive the Agent tool and should not be able to spawn a nested subagent, matching the 2.1.219 changelog and the pre-2.1.219 default behavior.

Steps to Reproduce

  1. Set CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 in the env block of ~/.claude/settings.json.
  2. Cold start Claude Code so the setting is read at session start. Confirm with echo $CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH from a Bash tool call, which should print 1.
  3. From the main session, spawn a level-1 subagent with subagent_type: "general-purpose". Instruct it to (a) report whether an Agent tool is present in its own toolset, and (b) actually issue one Agent call spawning another general-purpose subagent with a unique string to echo back.
  4. Observe the level-1 subagent has Agent and the nested spawn succeeds.
  5. Address the level-2 subagent directly and ask it to introspect its toolset and attempt the same. Observe it has no Agent tool.

Introspecting the toolset matters. A subagent that merely declines to call Agent is indistinguishable from one that was blocked, so the probe should require an actual attempt and an explicit tool-presence answer.

Observed

| Level | Spawned by | Agent tool present | Nested spawn |
|---|---|---|---|
| 1 | main session | yes | succeeded |
| 2 | level-1 subagent | no | not possible, tool absent |

Both levels were subagent_type: "general-purpose", and both read depth=[1] from their own shell environment, so the value does propagate into subagent environments.

The level-2 block presents as tool absence rather than an error, which is consistent with the documented mechanism ("A subagent at depth five doesn't receive the Agent tool and can't spawn further"). So the depth counter is being consulted. It is just off by one against the documented meaning of the value.

Why this looks like a regression rather than the intended reading

Two existing reports independently show that at depth 1 a general-purpose subagent has no Agent tool, which is the behavior this report says is now missing:

  • #80036 (2.1.217, darwin) reports general-purpose and claude subagents coming back with no Agent/Task tool and being unable to nest at all. That was during the window when the default was 1.
  • #83720 (2.1.221, cloud) reports the same tool absence with the value stuck at 1, and states the expected mapping directly: depth 2 is what should permit nesting one layer deep.

On 2.1.225 the identical configuration produces one layer of nesting. That points at a change in depth accounting somewhere in 2.1.222 through 2.1.225.

This is not a duplicate of #83720. That report is about the value failing to propagate through cloud config surfaces. Here the value propagates correctly and is readable in every subagent's environment; the defect is in how it is applied.

Related

  • #80083 notes the sub-agents docs still describe a fixed, non-configurable depth cap and never document how depth is counted. That missing definition is what makes this ambiguous to diagnose from the outside. Whichever way this is resolved, documenting the counting convention (does the main session occupy a level?) and the exact depth at which the Agent tool is withheld would prevent the next instance.

Claude Code Version

2.1.225

Platform

Anthropic API

Operating System

macOS (darwin 25.5.0)

Is this a regression?

Yes, suspected in 2.1.222 through 2.1.225.

Last Working Version

2.1.221 per #83720, and 2.1.217 per #80036, though neither was testing this exact assertion.

View original on GitHub ↗

3 Comments

bcherny collaborator · 14 days ago

Thanks for the detailed report. I tried to reproduce this on the released 2.1.233 (macOS, first-party API), and also on 2.1.227:

  • Set CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 (once via the shell environment, once via the env block of a settings.json), started a fresh session, and had the main session spawn a general-purpose subagent that was told to (a) list its tools and say whether Agent is present, and (b) actually attempt an Agent call.
  • Result both times: the level-1 subagent had no Agent tool, and its attempted call failed with No such tool available: Agent. So on 2.1.233 the setting works as documented (https://code.claude.com/docs/en/env-vars): 1 turns nesting off, and the level-1 subagent is the leaf.

The intended behavior matches your expectation, so if you're still seeing one extra level on your machine there is something environment-specific going on. Could you re-test on 2.1.233 and share:

  • claude doctor output and whether the session was interactive or -p
  • whether anything else sets that variable (a project .claude/settings.json, managed settings, CLAUDE_CONFIG_DIR)
  • a /share link (or transcript excerpt) from the session where the nested spawn succeeded, so we can see exactly how the level-1 agent was spawned

🤖 Generated with Claude Code

github-actions[bot] · 14 days ago

We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected? This issue will be closed automatically if there's no activity within 7 days.

oscarsterling · 13 days ago

Thanks for checking. Re-tested today on 2.1.234 (auto-updated overnight from 2.1.233) and it still reproduces here.

Setup

  • claude doctor: Running: native (2.1.234), Commit 7215ba60b06d, darwin-arm64, config install method native, "No installation issues found."
  • Session: interactive (tmux pane, claude with no -p).
  • The variable is set in exactly one place: ~/.claude/settings.json"env": { "CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "1" }. Not in settings.local.json, not in a project .claude/settings.json, no managed-settings file, CLAUDE_CONFIG_DIR unset. The main session's environment shows the variable present (inherited from that env block).

Repro, verbatim

  1. From the interactive main session, spawn one subagent via the Agent tool: subagent_type: general-purpose, model: opus, prompt asking it to (a) list its tools and say whether Agent is present, (b) call Agent once with prompt "reply with the single word DEPTH2", (c) run claude --version.
  2. The level-1 subagent reported Agent present in its always-loaded tool set (not deferred), then its Agent call ran and returned:
DEPTH2
agentId: ab3b6b116d8eee5eb ...
<usage>subagent_tokens: 38475 tool_uses: 0 duration_ms: 1742</usage>
  1. claude --version inside the level-1 subagent: 2.1.234 (Claude Code).

So with the setting at 1, a level-2 agent was created. Same shape as the original report on 2.1.225: effective depth is one greater than configured.

Difference from your repro that may matter: the variable here comes from the user-level settings.json env block, and the session is interactive with a large MCP/plugin surface loaded (Linear, Telegram, Deep Memory, GitHub, Chrome, etc.). Happy to run any specific probe you name; I can also share a transcript excerpt of the level-1 agent's tool list and call result if that helps more than a /share link.