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

  1. Wait for completion events from queued/running agents and retry the spawn when a slot frees
  2. Cancel unneeded agents to release admitted slots immediately
  3. Raise the limit: set [subagents] max_admitted in config (or with_admission_limit at construction) sized for the workflow's real fan-out
  4. 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

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


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/570e5c90ea302b5c. Report an issue: GitHub.