agents.max_depth = 1 permits child-to-grandchild spawning in 0.144.1
Codex version
Codex CLI 0.144.1, macOS arm64. This is the latest stable GitHub release as of 2026-07-10.
Configuration
[agents]
max_depth = 1
max_threads = 50
The configuration passes:
codex --strict-config --version
with:
codex-cli 0.144.1
There is no project-local Codex config overriding the user-level agents table.
Reproduction
- Start a fresh Codex task.
- Have the root thread spawn one direct child.
- Have that child make exactly one no-op subagent spawn attempt.
- Observe that the spawn succeeds and the grandchild runs.
Observed spawned path shape:
/root/explorer_depth_probe/noop
The grandchild returned only NOOP, so the probe made no repository or external changes.
Expected behavior
The official Subagents documentation says agents.max_depth defaults to 1, the root starts at depth 0, and max_depth = 1 lets the root spawn direct children while preventing those children from spawning deeper descendants:
https://developers.openai.com/codex/subagents
Actual behavior
A direct child successfully spawned a grandchild despite agents.max_depth = 1.
Additional verification
- All custom agent TOMLs parse.
- The user config contains exactly agents.max_depth = 1.
- Codex strict config accepts the setting.
- No custom agent file defines another agents table or overrides max_depth.
- The no-op grandchild completed successfully, so this was not only a UI display artifact.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Still reproducible on 0.144.6, and I think I have the root cause. Short version: the depth check only exists in the V1 multi-agent handler, and the model catalog can silently put you on V2, which has no depth check at all.
Root cause
At tag
rust-v0.144.6(commit5d1fbf26c43abc65a203928b2e31561cb039e06d):core/src/tools/handlers/multi_agents/spawn.rs:64-71— the V1 handler enforces:core/src/tools/handlers/multi_agents_v2/spawn.rs— the V2 handler's complete set of depth references:It computes
child_depth, records it intothread_spawn_source, and never callsexceeds_thread_spawn_depth_limit. So on V2,agents.max_depthis accepted, range-validated (agents.max_depth must be at least 1fires for0), and then has no effect. The depth is still recorded correctly, which is what makes this so easy to miss —thread_spawn_edgesand each subagent'ssession_metashowdepth: 1, 2, 3faithfully while nothing enforces it.Why you were on V2 without asking for it
codex features listreportsmulti_agent_v2 under development false, but the model catalog overrides that.codex debug modelson 0.144.6:Every turn of mine on the default
gpt-5.6-solrecorded"multi_agent_version":"v2"inturn_context, despite the feature flag being false. This is the same mechanism reported in #31097.Reproduction, both directions
codex exec,agents.max_depth=1passed with--strict-configeach time, chain verified fromthread_spawn_edgesrather than model self-report:| Model | Runtime | Result |
|---|---|---|
|
gpt-5.6-sol(default) | v2 |/root/c1/c2/c3— depth 3 againstmax_depth=1||
gpt-5.6-luna| v1 | chain stops at depth 1 — correct |Workaround, and a note on how V1 actually enforces
-m gpt-5.6-luna(or any model whose catalogmulti_agent_versionisv1) makesagents.max_depthwork.Worth noting for anyone debugging this: on V1 the enforcement is not the
RespondToModelstring above — it never appears. The collaboration tools are simply withheld from an agent at the depth limit. Atmax_depth=1the depth-1 child's rollout contains zero occurrences ofmulti_agent_v1,send_input,close_agent, orresume_agent(vs 16/4/4/2 in the root's), and the child reports"No \spawn_agent\tool is available.". Atmax_depth=3that same child has the tools and reaches depth 2. That is arguably the better design — capability removal rather than asking the model to comply — so the fix here may be to give V2 the same treatment rather than to port the string check.Suggested fix
Either add the depth guard to
multi_agents_v2/spawn.rs, or (preferably) apply V1's tool-withholding to V2. Failing that,agents.max_depthshould at minimum error at config load when the resolved runtime is V2, rather than accepting a setting it will ignore.Environment:
codex-cli 0.144.6, macOS arm64,codex exec,~/.codex/config.tomlsets noagents.*keys (all limits passed via-c).Additional reproduction: Codex CLI 0.146.0 on Linux/WSL
I can reproduce the same failure on a current Linux/WSL installation, using the native collaboration tools (not a UI-only tree and not a nested
codex execprocess).Environment:
0.146.0gpt-5.6-terramulti_agent_version: "v2"``
toml
``[agents]
max_depth = 1
A real run produced this sanitized tree:
The corresponding session metadata contains
source.subagent.thread_spawn.depth: 2and records the depth-2 agents as nativeexplorersubagents. The grandchildren completed successfully, so this is an actual dispatch result rather than a display artifact.In the 0.146.0 binary/config description,
agents.max_depthis marked(V1 only; ignored by V2), but the key is still accepted without a warning or configuration error while the resolved session is V2. This creates a particularly dangerous silent-failure mode: a user can verify that the setting parses and still receive a deeper tree than the declared limit.Expected: with
max_depth = 1, a depth-1 child must not be able to spawn a depth-2 descendant, or Codex should reject/warn that the setting is unsupported for the resolved V2 runtime and identify the supported replacement.Actual: V2 accepts the setting, records depth 2, and allows the descendant to run.
This confirms that the issue remains present in
0.146.0and is not limited to the original macOS/0.144.1 report. The GSD-side capability mismatch is tracked separately in open-gsd/gsd-core#2939.