Hmbown/CodeWhale · warning
Sub-agent admission limit reached (max_admitted {}, admitted
Error message
Sub-agent admission limit reached (max_admitted {}, admitted {}, running {}, queued {}). Wait for queued/running agents to finish, cancel unneeded agents, or raise [subagents] max_admitted for this Workflow. What it means
The manager enforces an admission ceiling: when admitted_count() (queued plus running children) reaches max_admitted_agents, new spawns are refused with this backpressure error, which reports the cap and the current admitted/running/queued split. This is designed flow control, not corruption — the message itself lists the remedies (wait, cancel, or raise [subagents] max_admitted). The cap can be raised at runtime via with_admission_limit, clamped to a global maximum.
Source
Thrown at crates/tui/src/tools/subagent/mod.rs:6203
&& agent.task_handle.is_some()
&& !self.running_heartbeat_timed_out(agent)
&& self
.worker_records
.get(&agent.id)
.is_some_and(|record| record.status == AgentWorkerStatus::Queued)
})
.count()
}
/// Count admitted workers not currently in the queued launch state.
pub fn active_count(&self) -> usize {
self.admitted_count().saturating_sub(self.queued_count())
}
fn check_admission_capacity(&self) -> Result<()> {
let admitted = self.admitted_count();
if admitted >= self.max_admitted_agents {
return Err(anyhow!(
"Sub-agent admission limit reached (max_admitted {}, admitted {}, running {}, queued {}). Wait for queued/running agents to finish, cancel unneeded agents, or raise [subagents] max_admitted for this Workflow.",
self.max_admitted_agents,
admitted,
self.active_count(),
self.queued_count()
));
}
Ok(())
}
fn running_heartbeat_timed_out(&self, agent: &SubAgent) -> bool {
agent.status == SubAgentStatus::Running
&& agent.task_handle.is_some()
&& agent.last_activity_at.elapsed() >= self.running_heartbeat_timeout
}
pub fn touch(&mut self, agent_id: &str) -> bool {
let Some(agent) = self.agents.get_mut(agent_id) else {View on GitHub (pinned to 0c42157ee5)
Solutions
- Wait for completion events from queued/running agents and retry the spawn when a slot frees
- Cancel unneeded agents to release admitted slots immediately
- Raise the limit: set [subagents] max_admitted in config (or with_admission_limit at construction) sized for the workflow's real fan-out
- Audit for stuck Running agents via manager.list() — reaping them frees slots without new work
Example fix
// before
let agent = spawn(request).await?;
// after
loop {
match spawn(request.clone()).await {
Ok(agent) => break Ok(agent),
Err(e) if e.to_string().contains("admission limit reached") => {
wait_for_agent_completion_event().await; // backpressure, then retry
}
Err(e) => break Err(e),
}
} Defensive patterns
Strategy: retry
Validate before calling
// Cheap gate before spawning in fan-out loops.
let admitted = manager.list().len(); // queued + running snapshot
if admitted >= expected_admission_cap {
wait_for_completion_event().await; // backpressure before the call
} Try / catch
Loop the spawn on errors whose message contains 'admission limit reached': await one agent completion event per retry so the loop always makes progress; cap total wait time and surface the last error on timeout.
Prevention
- Size [subagents] max_admitted (or with_admission_limit) to the workflow's genuine parallelism before running fan-outs
- Consume completion events to drive the next spawn instead of spawning the whole batch up front
- Cancel agents whose output is no longer needed — cancelled slots free admission immediately
When it happens
Trigger: Spawning more sub-agents than max_admitted before earlier ones finish; fan-out (map over many tasks) exceeding the configured ceiling; stuck Running agents (e.g., heartbeat issues or very long tasks) holding all admitted slots; queued agents counting toward admitted while launch concurrency is lower.
Common situations: Large parallel workflows (batch refactors, multi-file research) exceeding the default admission cap; one slow worker blocking a whole wave of new spawns; admission reduced for testing and forgotten before a production run.
Related errors
- context_window must be greater than 0
- custom provider '{provider_id}' must set [providers.{provide
- unknown field '{field_key}' for built-in provider '{provider
- unknown field '{field_key}' for custom provider '{provider_i
- invalid boolean '{raw}'
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/570e5c90ea302b5c.
Report an issue: GitHub.