Hmbown/CodeWhale · error

Sub-agent depth limit reached

Error message

Sub-agent depth limit reached (child depth {}, absolute max {})

What it means

During sub-agent admission, the runtime's max spawn depth is clamped to the worker profile's limit; if the child's would-be depth exceeds that absolute max, spawn is refused. This is the fresh-spawn counterpart of the resume-path depth check.

Solutions

  1. Flatten the delegation: have a shallower agent perform or spawn the work.
  2. Raise `max_spawn_depth` in `[subagents]` or in the relevant worker profile.
  3. Check for runaway recursive spawning and add a termination condition to the delegating prompt/logic.

Example fix

// before
[worker_profiles.researcher]
max_spawn_depth = 1

// after
[worker_profiles.researcher]
max_spawn_depth = 3
Defensive patterns

Strategy: validation

Validate before calling

fn can_spawn_at(depth: usize, cfg: &SubagentsConfig, profile: &WorkerProfile) -> bool {
    depth <= cfg.max_spawn_depth.min(profile.max_spawn_depth)
}

Try / catch

match spawn_child(task) {
    Err(e) if e.to_string().contains("depth limit reached") => run_inline(task), // do it yourself, no child
    other => other?,
}

Prevention

When it happens

Trigger: Spawning a sub-agent whose computed `spawn_depth` exceeds `min(runtime.max_spawn_depth, worker_profile.max_spawn_depth)` — e.g. a grandchild spawned at depth greater than the configured `max_spawn_depth`, or a worker profile with a tighter depth cap.

Common situations: Deeply nested agent chains (child spawning child spawning child); a worker profile configured with a small `max_spawn_depth`; recursive task delegation that never bottoms out.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a9aa7aa1fd53bd6a. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/subagent/mod.rs:6854

        assignment: SubAgentAssignment,
        allowed_tools: Option<Vec<String>>,
        options: SubAgentSpawnOptions,
        precomputed_delivery_evidence: Option<DeliveryEvidence>,
    ) -> Result<SubAgentResult> {
        // Every manager-spawned runtime carries the fleet governor, so the
        // spawned agent and its whole descendant tree report 429s/successes
        // to the adaptive scheduler. Runtimes built outside a manager (tests,
        // tool-only runtimes) keep `governor: None`.
        runtime.governor = Some(Arc::clone(&self.governor));

        self.cleanup(COMPLETED_AGENT_RETENTION);

        self.check_admission_capacity()?;
        runtime.max_spawn_depth = runtime
            .max_spawn_depth
            .min(runtime.worker_profile.max_spawn_depth);
        if runtime.spawn_depth > runtime.max_spawn_depth {
            return Err(anyhow!(
                "Sub-agent depth limit reached (child depth {}, absolute max {})",
                runtime.spawn_depth,
                runtime.max_spawn_depth
            ));
        }
        // A continuation/fork keeps the source's allowance as well as its
        // current parent's allowance. The manifest edge preserves this after
        // reload and for descendant accounting.
        if let Some(preserved) = options.preserve_runtime_profile.as_ref() {
            runtime.spawn_depth = runtime.spawn_depth.max(preserved.spawn_depth);
            runtime.max_spawn_depth = runtime.max_spawn_depth.min(preserved.max_spawn_depth);
            runtime.worker_profile.max_steps =
                narrow_model_steps(runtime.worker_profile.max_steps, preserved.max_steps);
            runtime.worker_profile.wall_time_secs = narrow_optional_limit(
                runtime.worker_profile.wall_time_secs,
                preserved.wall_time_secs,
            );
            runtime.worker_profile.wall_deadline_ms = narrow_optional_limit(

View on GitHub (pinned to 73e0f67d83)