Skip to content

agents.max_depth = 1 permits child-to-grandchild spawning in 0.144.1 #32027

Open

Description

@EatMyTarts

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

  1. Start a fresh Codex task.
  2. Have the root thread spawn one direct child.
  3. Have that child make exactly one no-op subagent spawn attempt.
  4. 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.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    subagentIssues involving subagents or multi-agent features
    configIssues involving config.toml, config keys, config merging, or config updates
    on Jul 10, 2026
  2. github-actions commented on Jul 10, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. adrianto-nanovest commented on Jul 29, 2026

    @adrianto-nanovest

    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 (commit 5d1fbf26c43abc65a203928b2e31561cb039e06d):

    core/src/tools/handlers/multi_agents/spawn.rs:64-71 — the V1 handler enforces:

    let child_depth = next_thread_spawn_depth(&session_source);
    let max_depth = turn.config.agent_max_depth;
    if exceeds_thread_spawn_depth_limit(child_depth, max_depth) {
        return Err(FunctionCallError::RespondToModel(
            "Agent depth limit reached. Solve the task yourself.".to_string(),
        ));
    }

    core/src/tools/handlers/multi_agents_v2/spawn.rs — the V2 handler's complete set of depth references:

     4: use crate::agent::next_thread_spawn_depth;
    61:     let child_depth = next_thread_spawn_depth(&session_source);
    98:         child_depth,
    

    It computes child_depth, records it into thread_spawn_source, and never calls exceeds_thread_spawn_depth_limit. So on V2, agents.max_depth is accepted, range-validated (agents.max_depth must be at least 1 fires for 0), and then has no effect. The depth is still recorded correctly, which is what makes this so easy to miss — thread_spawn_edges and each subagent's session_meta show depth: 1, 2, 3 faithfully while nothing enforces it.

    Why you were on V2 without asking for it

    codex features list reports multi_agent_v2 under development false, but the model catalog overrides that. codex debug models on 0.144.6:

    gpt-5.6-sol    multi_agent_version: v2
    gpt-5.6-terra  multi_agent_version: v2
    gpt-5.6-luna   multi_agent_version: v1
    gpt-5.5        multi_agent_version: null
    gpt-5.4        multi_agent_version: null
    

    Every turn of mine on the default gpt-5.6-sol recorded "multi_agent_version":"v2" in turn_context, despite the feature flag being false. This is the same mechanism reported in #31097.

    Reproduction, both directions

    codex exec, agents.max_depth=1 passed with --strict-config each time, chain verified from thread_spawn_edges rather than model self-report:

    Model Runtime Result
    gpt-5.6-sol (default) v2 /root/c1/c2/c3 — depth 3 against max_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 catalog multi_agent_version is v1) makes agents.max_depth work.

    Worth noting for anyone debugging this: on V1 the enforcement is not the RespondToModel string above — it never appears. The collaboration tools are simply withheld from an agent at the depth limit. At max_depth=1 the depth-1 child's rollout contains zero occurrences of multi_agent_v1, send_input, close_agent, or resume_agent (vs 16/4/4/2 in the root's), and the child reports "No \spawn_agent` tool is available.". At max_depth=3` that 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_depth should 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.toml sets no agents.* keys (all limits passed via -c).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingconfigIssues involving config.toml, config keys, config merging, or config updatessubagentIssues involving subagents or multi-agent features

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions