[BUG] CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 does not disable nesting on 2.1.225; effective depth is one level greater than configured
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
- Set
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1in theenvblock of~/.claude/settings.json. - Cold start Claude Code so the setting is read at session start. Confirm with
echo $CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHfrom a Bash tool call, which should print1. - From the main session, spawn a level-1 subagent with
subagent_type: "general-purpose". Instruct it to (a) report whether anAgenttool is present in its own toolset, and (b) actually issue oneAgentcall spawning anothergeneral-purposesubagent with a unique string to echo back. - Observe the level-1 subagent has
Agentand the nested spawn succeeds. - Address the level-2 subagent directly and ask it to introspect its toolset and attempt the same. Observe it has no
Agenttool.
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-purposeandclaudesubagents coming back with noAgent/Tasktool 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
Agenttool 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.
3 Comments
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:
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1(once via the shell environment, once via theenvblock of asettings.json), started a fresh session, and had the main session spawn ageneral-purposesubagent that was told to (a) list its tools and say whetherAgentis present, and (b) actually attempt anAgentcall.Agenttool, and its attempted call failed withNo such tool available: Agent. So on 2.1.233 the setting works as documented (https://code.claude.com/docs/en/env-vars):1turns 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 doctoroutput and whether the session was interactive or-p.claude/settings.json, managed settings,CLAUDE_CONFIG_DIR)/sharelink (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
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.
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."claudewith no-p).~/.claude/settings.json→"env": { "CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "1" }. Not insettings.local.json, not in a project.claude/settings.json, no managed-settings file,CLAUDE_CONFIG_DIRunset. The main session's environment shows the variable present (inherited from that env block).Repro, verbatim
Agenttool:subagent_type: general-purpose,model: opus, prompt asking it to (a) list its tools and say whetherAgentis present, (b) callAgentonce with prompt "reply with the single word DEPTH2", (c) runclaude --version.Agentpresent in its always-loaded tool set (not deferred), then itsAgentcall ran and returned:claude --versioninside 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.jsonenvblock, 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/sharelink.