{"record":{"id":"f93bb619f4d64e6d","repo":"Hmbown/CodeWhale","slug":"child-wall-time-budget-exhausted-limit-s-partial-work-is","errorCode":null,"errorMessage":"child wall-time budget exhausted (limit: {}s); partial work is preserved; narrow the task or have the operator raise the inherited limit","messagePattern":"child wall-time budget exhausted \\(limit: (.+?)s\\); partial work is preserved; narrow the task or have the operator raise the inherited limit","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/subagent/mod.rs","lineNumber":11608,"sourceCode":"    }\n\n    let turn_end_parking = task\n        ._foreground_child_registration\n        .as_ref()\n        .map(ForegroundChildRegistration::parking_signal);\n    // Every inner stage bounds itself by `deadline` (step requests by the\n    // work deadline, and the reserved hand-back turn by the hard deadline),\n    // so the inner run can always produce its own receipt: the specific stop\n    // cause, the hand-back outcome, and preserved usage. This outer backstop\n    // exists only for an inner stage that overruns anyway; racing it at the\n    // same instant as the inner deadline replaced real receipts with the\n    // generic error below (#6277). The grace keeps the anti-hang guarantee\n    // while letting the inner receipt win.\n    let backstop = deadline + Duration::from_secs(30);\n    let effective_limit = deadline.saturating_duration_since(task.started_at);\n    let result = if launch_wait_timed_out {\n        task.runtime.cancel_token.cancel();\n        Err(anyhow!(child_wall_time_exhausted_reason(effective_limit)))\n    } else {\n        tokio::time::timeout_at(\n            backstop.into(),\n            run_subagent(\n                &task.runtime,\n                task.agent_id.clone(),\n                task.agent_type,\n                task.prompt,\n                task.assignment,\n                task.allowed_tools,\n                task.fork_context,\n                task.started_at,\n                task.max_steps,\n                turn_end_parking,\n                task.input_rx,\n            ),\n        )\n        .await","sourceCodeStart":11590,"sourceCodeEnd":11626,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/subagent/mod.rs#L11590-L11626","documentation":"When launching a sub-agent, the launch wait has a deadline; if launching itself times out (launch_wait_timed_out), the child's cancel token is fired and this error is returned immediately via child_wall_time_exhausted_reason. A 30-second backstop beyond the deadline is kept so a graceful inner receipt can still win, but the hard anti-hang guarantee stands: the child gets no more than its inherited wall-time budget plus grace.","triggerScenarios":"A sub-agent task whose startup/launch phase does not complete within its inherited wall-time deadline — the launch wait times out, cancellation is triggered, and this error is surfaced with the effective limit in seconds.","commonSituations":"A task prompt that is far too broad for its budget, an operator-configured deadline that is too small for the task, or a child hanging during startup (blocked tool, dead provider) so it never finishes launching in time.","solutions":["Narrow the sub-agent task so it fits within the inherited wall-time budget","Have the operator raise the child's time limit in the runtime envelope/config","Check for a hanging tool call or provider request keeping the child from finishing startup","Inspect the child's partial work (it is preserved) to see where the time went"],"exampleFix":"// before: broad task on a tight inherited budget\nsubagent.run(\"refactor the entire module\", limit = 60s);\n// after: narrowed task, or raised operator limit\nsubagent.run(\"rename Foo to Bar in module X\", limit = 300s);","handlingStrategy":"try-catch","validationCode":"let budget = child.time_limit();\nif estimated_task_duration > budget {\n    return Err(\"task too broad for inherited limit; narrow it\".into());\n}","typeGuard":null,"tryCatchPattern":"match run_subagent_task(task).await {\n    Err(e) if e.to_string().contains(\"wall-time budget exhausted\") => {\n        // partial work is preserved; inspect and resume with a narrower task\n        resume_from_partial(&task.agent_id)?\n    }\n    other => other,\n}","preventionTips":["Size tasks to fit their inherited time budget","Avoid tasks that can hang on a single provider call; add step-level timeouts","Inspect preserved partial work after a timeout before retrying"],"tags":["subagent","timeout","budget"],"backgroundTag":"request-timeout","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"}