Hmbown/CodeWhale · error
Sub-agent token budget exhausted; continuation cannot reset…
Error message
Sub-agent token budget exhausted; continuation cannot reset its inherited allowance
What it means
This error is thrown in `spawn_background_with_assignment_options` (crates/tui/src/tools/subagent/mod.rs:6938) when a sub-agent is spawned or continued and its inherited token allowance is exactly zero. Continuations and forks inherit the remaining token budget of their source/parent agent (`resume_from_agent_id` or `runtime.parent_agent_id`); the library refuses the spawn because a new child could never run any model turns under an empty allowance, and starting it would silently reset the accounting. It is an explicit anti-loophole guard: a continuation must live inside the parent's remaining budget, not mint a fresh one.
Solutions
- Finish the parent agent's task or accept it is done; do not continue a fully spent agent.
- Spawn a fresh sub-agent with an explicit, larger `token_budget` option instead of continuing the exhausted one.
- Raise the token budget on the parent/source worker profile so `remaining_worker_tokens` is positive before continuing.
- Increase `default_token_budget` in the sub-agent manager config so newly spawned workers get a larger allowance.
Example fix
// before: continuing an exhausted agent
spawn_background_with_assignment_options(handle, runtime, role, prompt, assignment, tools,
SubAgentSpawnOptions { resume_from_agent_id: Some(spent_agent_id), .. })
// after: fresh agent with a new budget
spawn_background_with_assignment_options(handle, runtime, role, prompt, assignment, tools,
SubAgentSpawnOptions { token_budget: Some(64_000), .. }) Defensive patterns
Strategy: validation
Validate before calling
fn can_continue(manager: &SubAgentManager, options: &SubAgentSpawnOptions, runtime: &SubAgentRuntime) -> bool {
let parent = options.resume_from_agent_id.as_deref()
.or(runtime.parent_agent_id.as_deref());
match parent.map(|id| manager.remaining_worker_tokens(id)) {
Some(Some(0)) => false,
_ => true,
}
} Type guard
fn has_inherited_budget(remaining: Option<u64>) -> bool {
remaining.map_or(true, |r| r > 0)
} Try / catch
match manager.spawn_background_with_assignment_options(handle, runtime, role, prompt, assignment, tools, options) {
Ok(result) => /* ... */,
Err(e) if e.to_string().contains("token budget exhausted") => {
// fall back to spawning a fresh agent with a new token_budget
},
Err(e) => return Err(e),
} Prevention
- Check remaining_worker_tokens(source_id) before issuing any continuation.
- Track cumulative token spend per agent and stop issuing followups as the budget nears zero.
- Prefer spawning fresh agents with explicit token_budget over long continuation chains.
- Set realistic default_token_budget values so agents are not starved mid-task.
When it happens
Trigger: Calling the sub-agent spawn tool with `resume_from_agent_id` (or having a parent agent id set) when `remaining_worker_tokens(parent_id)` returns `Some(0)` — i.e. the parent/source worker already consumed its entire `token_budget`. Typical call: spawning a continuation/fork of an agent whose token allowance is fully spent.
Common situations: (1) A long-running sub-agent burned through its token budget and the orchestrator tries to continue it with a follow-up/fork. (2) Chained continuations where each generation narrows the inherited budget until it hits zero. (3) A misconfigured `token_budget` (or a very small per-call `token_budget` option) that is exhausted almost immediately, so any continuation attempt fails. (4) Resuming after a session reload where the manifest's preserved token budget was already fully consumed.
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
- child step budget exhausted; continuation cannot reset its…
- child wall-time budget exhausted; continuation cannot reset…
- Sub-agent depth limit reached
- agent action=claim widens an enforced write scope, and the…
- Agent has no continuable checkpoint to resume from…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/91dde0a596302227.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/mod.rs:6938
narrow_optional_limit(runtime.worker_profile.token_budget, preserved.token_budget);
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(
runtime.worker_profile.wall_deadline_ms,
preserved.wall_deadline_ms,
);
}
let budget_parent = options
.resume_from_agent_id
.as_deref()
.or(runtime.parent_agent_id.as_deref());
let inherited_remaining = budget_parent.and_then(|id| self.remaining_worker_tokens(id));
if inherited_remaining == Some(0) {
return Err(anyhow!(
"Sub-agent token budget exhausted; continuation cannot reset its inherited allowance"
));
}
let effective_token_budget = narrow_optional_limit(
narrow_optional_limit(runtime.worker_profile.token_budget, inherited_remaining),
narrow_optional_limit(
self.default_token_budget,
positive_token_budget(options.token_budget),
),
);
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))View on GitHub (pinned to 433685b202)