Hmbown/CodeWhale · error

child step budget exhausted; continuation cannot reset its…

Error message

child step budget exhausted; continuation cannot reset its model-turn allowance

What it means

When creating a continuation of an existing child, its remaining model-turn allowance (`max_steps - steps_taken`) is inherited; a continuation can never grant more turns than the source has left. If the source has zero remaining turns, no continuation is possible and this error is thrown.

Solutions

  1. Spawn a fresh child with a new step budget instead of continuing the exhausted one.
  2. Raise the source child's `max_steps` in its spec so it retains remaining turns.
  3. Make the continuation source a fork from an earlier checkpoint that still has budget left.
  4. If auto-continuing, stop when remaining == 0 and surface completion/interruption instead.

Example fix

// before
if remaining == 0 { continue_child(source)?; }

// after
let remaining = source.spec.max_steps.saturating_sub(source.steps_taken);
if remaining == 0 {
    spawn_fresh_child(source.task, max_steps = default_budget)?;
} else {
    continue_child(source)?;
}
Defensive patterns

Strategy: validation

Validate before calling

let remaining = source.spec.max_steps.saturating_sub(source.steps_taken);
if source.spec.max_steps > 0 && remaining == 0 {
    // spawn fresh child instead of continuing
}

Try / catch

match continue_child(source) {
    Err(e) if e.to_string().contains("step budget exhausted") => spawn_fresh_child(source.task),
    other => other?,
}

Prevention

When it happens

Trigger: Spawning a continuation/fork of a child whose `source.spec.max_steps > 0` and `source.steps_taken == source.spec.max_steps` (budget exactly exhausted); the check runs before `narrow_model_steps` narrows the continuation's allowance.

Common situations: A child that burned its entire step budget and is then asked to continue; an auto-continue loop that keeps continuing a fully exhausted child; `max_steps` set too low for the task.

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/f809da575b8483bc. Report an issue: GitHub.

Appendix: source

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

                preserved.wall_deadline_ms,
            );
        }
        // #6282: spawn options narrow the per-result output cap.
        runtime.max_output_tokens =
            narrow_optional_limit(runtime.max_output_tokens, options.max_output_tokens);
        let mut max_steps = narrow_model_steps(
            runtime.worker_profile.max_steps,
            resolve_max_steps(agent_type.clone(), options.max_steps, self.max_steps),
        );
        if let Some(source) = options
            .resume_from_agent_id
            .as_deref()
            .and_then(|id| self.worker_records.get(id))
        {
            if source.spec.max_steps > 0 {
                let remaining = source.spec.max_steps.saturating_sub(source.steps_taken);
                if remaining == 0 {
                    return Err(anyhow!(
                        "child step budget exhausted; continuation cannot reset its model-turn allowance"
                    ));
                }
                max_steps = narrow_model_steps(max_steps, remaining);
            }
            // A source's absolute position is part of its authority. A fork
            // requested by root cannot turn a depth-2 leaf into a depth-1
            // worker and thereby regain a generation of delegation.
            runtime.spawn_depth = runtime
                .spawn_depth
                .max(source.spec.spawn_depth)
                .max(source.spec.runtime_profile.spawn_depth);
            runtime.max_spawn_depth = runtime.max_spawn_depth.min(source.spec.max_spawn_depth);
        }
        if runtime.spawn_depth > runtime.max_spawn_depth {
            return Err(anyhow!(
                "Sub-agent depth limit reached (child depth {}, absolute inherited max {})",
                runtime.spawn_depth,

View on GitHub (pinned to 73e0f67d83)