[agents] max_depth not enforced for nested spawn_agent (0.155.1)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Problem
[agents] max_depth = 1 does not prevent a depth-1 worker from calling spawn_agent to create a depth-2 leaf in codex-cli 0.155.1. Changing the value to 0 and launching a fresh CLI process also permits both spawns. Neither test returns the depth-limit refusal.
Environment
- Reproduced on 2026-09-19, native Arch Linux, x86_64.
codex --version:codex-cli 0.155.1(standalone x86_64-unknown-linux-musl distribution).- Model:
gpt-6-astra. codex features list:multi_agentstable/true;multi_agent_v2stable/false.- Scratch directory outside a Git repository, fresh
codex execprocess for each run. - App-server
config/readwithincludeLayers:trueconfirmsagents.max_depthoriginates from the user~/.codex/config.toml, with no selected profile. No project-level override or CODEX_HOME override was involved.
Relevant global config, tested separately with values 1 and 0:
[agents]
max_depth = 1
max_concurrent_threads_per_session = 10
Reproduction
- Set
agents.max_depth = 1in the global config. - Start a fresh process from an empty scratch directory:
codex exec --skip-git-repo-check -C /tmp/codex-depth-scratch --json \
'Depth-cap diagnostic: call spawn_agent once to create worker. Tell worker to call spawn_agent once to create leaf, instructing leaf to reply LEAF_OK and never spawn. Wait for both and report exact tool outcomes. Nested spawn is explicitly requested for this test.'
- Observe main creates worker; worker creates leaf; leaf replies
LEAF_OK. - Change only
max_depthto0, restart through a freshcodex execprocess, and repeat. Both spawns still succeed.
Observed evidence
Sanitized metadata from persisted rollout JSONL files (session_meta.payload.source.subagent.thread_spawn):
| Config value | Thread ID | Parent thread ID | Depth | Agent path |
|---|---|---|---|---|
| 1 | 01a0bb47-d161-73a1-a613-6d701d1813a4 |
01a0bb47-ad50-74b2-b55d-bbe92f1e4cd3 |
1 | /root/depth_probe |
| 1 | 01a0bb47-f2c6-70e0-b8fc-0e2144e48d1e |
01a0bb47-d161-73a1-a613-6d701d1813a4 |
2 | /root/depth_probe/depth_leaf |
| 0 | 01a0bb4d-0470-7ed1-abb0-0f139707c7ee |
01a0bb4c-e074-7b11-9ec3-cef74195b45a |
1 | /root/depth_zero_worker |
| 0 | 01a0bb4d-189e-7532-b573-ccd3ec23b875 |
01a0bb4d-0470-7ed1-abb0-0f139707c7ee |
2 | /root/depth_zero_worker/depth_zero_leaf |
For the max_depth=0 run, actual collaboration.spawn_agent tool results were:
{"task_name":"/root/depth_zero_worker"}
{"task_name":"/root/depth_zero_worker/depth_zero_leaf"}
Leaf response: LEAF_OK. Fresh app-server effective config read while testing returned agents.max_depth: 0, origin user config, profile null.
Expected behavior
With max_depth = 1, main (depth 0) may spawn workers (depth 1), but workers must not spawn depth-2 children. The binary contains the refusal string:
Agent depth limit reached. Solve the task yourself.
No such refusal occurred with either value. Whether zero should forbid every spawn or has special semantics needs clarification; it did not provide the desired one-level cap.
Additional checks
codex --help, codex config --help (which prints top-level help; no config subcommand is listed), and executable strings for max_depth|depth_limit|thread_spawn did not expose a replacement depth-setting key. The binary includes max_depth among agent config fields as well as the refusal string. Current online configuration reference omits the field, so it is unclear whether it is intended to remain supported on this spawn path. No speculative alternative keys were installed.
The config has been restored byte-for-byte to its original value of 1. No AGENTS.md workaround was added. Raw rollouts and full config are intentionally omitted to avoid publishing unrelated local data.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the agents.max_depth configuration into the collaboration.spawn_agent path, using the provided fresh-process codex exec reproduction for values 1 and 0. Check how thread depth is recorded in session_meta.payload.source.subagent.thread_spawn and where the refusal text is emitted. Done means depth-1 workers cannot create depth-2 children when max_depth is 1, with the intended zero-value behavior clarified and covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- ai-infra-agents, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100