{"record":{"id":"f809da575b8483bc","repo":"Hmbown/CodeWhale","slug":"child-step-budget-exhausted-continuation-cannot-reset-its","errorCode":null,"errorMessage":"child step budget exhausted; continuation cannot reset its model-turn allowance","messagePattern":"child step budget exhausted; continuation cannot reset its model-turn allowance","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":6892,"sourceCode":"                preserved.wall_deadline_ms,\n            );\n        }\n        // #6282: spawn options narrow the per-result output cap.\n        runtime.max_output_tokens =\n            narrow_optional_limit(runtime.max_output_tokens, options.max_output_tokens);\n        let mut max_steps = narrow_model_steps(\n            runtime.worker_profile.max_steps,\n            resolve_max_steps(agent_type.clone(), options.max_steps, self.max_steps),\n        );\n        if let Some(source) = options\n            .resume_from_agent_id\n            .as_deref()\n            .and_then(|id| self.worker_records.get(id))\n        {\n            if source.spec.max_steps > 0 {\n                let remaining = source.spec.max_steps.saturating_sub(source.steps_taken);\n                if remaining == 0 {\n                    return Err(anyhow!(\n                        \"child step budget exhausted; continuation cannot reset its model-turn allowance\"\n                    ));\n                }\n                max_steps = narrow_model_steps(max_steps, remaining);\n            }\n            // A source's absolute position is part of its authority. A fork\n            // requested by root cannot turn a depth-2 leaf into a depth-1\n            // worker and thereby regain a generation of delegation.\n            runtime.spawn_depth = runtime\n                .spawn_depth\n                .max(source.spec.spawn_depth)\n                .max(source.spec.runtime_profile.spawn_depth);\n            runtime.max_spawn_depth = runtime.max_spawn_depth.min(source.spec.max_spawn_depth);\n        }\n        if runtime.spawn_depth > runtime.max_spawn_depth {\n            return Err(anyhow!(\n                \"Sub-agent depth limit reached (child depth {}, absolute inherited max {})\",\n                runtime.spawn_depth,","sourceCodeStart":6874,"sourceCodeEnd":6910,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/mod.rs#L6874-L6910","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Spawn a fresh child with a new step budget instead of continuing the exhausted one.","Raise the source child's `max_steps` in its spec so it retains remaining turns.","Make the continuation source a fork from an earlier checkpoint that still has budget left.","If auto-continuing, stop when remaining == 0 and surface completion/interruption instead."],"exampleFix":"// before\nif remaining == 0 { continue_child(source)?; }\n\n// after\nlet remaining = source.spec.max_steps.saturating_sub(source.steps_taken);\nif remaining == 0 {\n    spawn_fresh_child(source.task, max_steps = default_budget)?;\n} else {\n    continue_child(source)?;\n}","handlingStrategy":"validation","validationCode":"let remaining = source.spec.max_steps.saturating_sub(source.steps_taken);\nif source.spec.max_steps > 0 && remaining == 0 {\n    // spawn fresh child instead of continuing\n}","typeGuard":null,"tryCatchPattern":"match continue_child(source) {\n    Err(e) if e.to_string().contains(\"step budget exhausted\") => spawn_fresh_child(source.task),\n    other => other?,\n}","preventionTips":["Check max_steps - steps_taken > 0 before creating a continuation","Set child max_steps generously for the expected task length","Stop auto-continue loops when the source budget is exhausted"],"tags":["subagent","budget","continuation","steps"],"backgroundTag":"value-out-of-range","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}