Hmbown/CodeWhale · error · anyhow::Error
child wall-time budget exhausted
Error message
child wall-time budget exhausted (limit: {}s); partial work is preserved; narrow the task or have the operator raise the inherited limit What it means
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.
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
Example fix
// before: broad task on a tight inherited budget
subagent.run("refactor the entire module", limit = 60s);
// after: narrowed task, or raised operator limit
subagent.run("rename Foo to Bar in module X", limit = 300s); Defensive patterns
Strategy: try-catch
Validate before calling
let budget = child.time_limit();
if estimated_task_duration > budget {
return Err("task too broad for inherited limit; narrow it".into());
} Try / catch
match run_subagent_task(task).await {
Err(e) if e.to_string().contains("wall-time budget exhausted") => {
// partial work is preserved; inspect and resume with a narrower task
resume_from_partial(&task.agent_id)?
}
other => other,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- child step budget exhausted; continuation cannot reset its…
- child wall-time budget exhausted; continuation cannot reset…
- child wall-time budget exhausted
- first timed-out API attempt should reach the test server
- Sub-agent token budget exhausted for scope
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/f93bb619f4d64e6d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/mod.rs:11608
}
let turn_end_parking = task
._foreground_child_registration
.as_ref()
.map(ForegroundChildRegistration::parking_signal);
// Every inner stage bounds itself by `deadline` (step requests by the
// work deadline, and the reserved hand-back turn by the hard deadline),
// so the inner run can always produce its own receipt: the specific stop
// cause, the hand-back outcome, and preserved usage. This outer backstop
// exists only for an inner stage that overruns anyway; racing it at the
// same instant as the inner deadline replaced real receipts with the
// generic error below (#6277). The grace keeps the anti-hang guarantee
// while letting the inner receipt win.
let backstop = deadline + Duration::from_secs(30);
let effective_limit = deadline.saturating_duration_since(task.started_at);
let result = if launch_wait_timed_out {
task.runtime.cancel_token.cancel();
Err(anyhow!(child_wall_time_exhausted_reason(effective_limit)))
} else {
tokio::time::timeout_at(
backstop.into(),
run_subagent(
&task.runtime,
task.agent_id.clone(),
task.agent_type,
task.prompt,
task.assignment,
task.allowed_tools,
task.fork_context,
task.started_at,
task.max_steps,
turn_end_parking,
task.input_rx,
),
)
.awaitView on GitHub (pinned to 73e0f67d83)