ruvnet/ruflo · error

Batch would exceed maximum concurrent agents

Error message

Batch would exceed maximum concurrent agents

What it means

Thrown by LifecycleManager.spawnBatch as a pre-flight capacity check: it fires when the number of agents currently in the pool plus configs.length would exceed the maxConcurrentAgents value from the LifecycleManagerConfig passed at construction. The check runs before any agent in the batch is spawned, so a failure means nothing was partially created. It keeps concurrent agent usage inside the configured ceiling.

Source

Thrown at v3/@claude-flow/shared/src/core/orchestrator/lifecycle-manager.ts:141

    // Mark as active
    agent.status = 'active';

    this.eventBus.emit(SystemEventTypes.AGENT_SPAWNED, {
      agentId: agent.id,
      profile: config,
      sessionId: undefined,
    });

    return agent;
  }

  async spawnBatch(configs: IAgentConfig[]): Promise<Map<string, IAgent>> {
    const results = new Map<string, IAgent>();

    // Check total capacity
    if (this.pool.size() + configs.length > this.config.maxConcurrentAgents) {
      throw new Error('Batch would exceed maximum concurrent agents');
    }

    // Spawn in parallel
    const spawnPromises = configs.map(async config => {
      try {
        const agent = await this.spawn(config);
        return { id: config.id, agent, error: null };
      } catch (error) {
        return { id: config.id, agent: null, error };
      }
    });

    const settled = await Promise.allSettled(spawnPromises);

    for (const result of settled) {
      if (result.status === 'fulfilled' && result.value.agent) {
        results.set(result.value.id, result.value.agent);
      }

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Free capacity first: call getAllAgents(), terminate() finished or idle agents so pool size + batch length fits under maxConcurrentAgents
  2. Split the batch into chunks of at most (maxConcurrentAgents - getAllAgents().length) and spawn in waves
  3. Raise maxConcurrentAgents in the LifecycleManagerConfig if the workload genuinely needs more concurrent agents
  4. If the cap keeps firing, treat it as a scheduling signal (await running agents) rather than removing the limit

Example fix

// before
await lifecycle.spawnBatch(allConfigs); // throws: batch would exceed cap

// after
const free = lifecycleConfig.maxConcurrentAgents - lifecycle.getAllAgents().length;
for (let i = 0; i < allConfigs.length; i += free) {
  await lifecycle.spawnBatch(allConfigs.slice(i, i + free));
}
Defensive patterns

Strategy: validation

Validate before calling

const cap = lifecycleConfig.maxConcurrentAgents;
const free = cap - lifecycle.getAllAgents().length;
if (batchConfigs.length > free) {
  const idle = lifecycle.getAllAgents().filter(a => a.status !== 'active');
  await Promise.all(idle.map(a => lifecycle.terminate(a.id)));
}
const chunk = Math.max(1, cap - lifecycle.getAllAgents().length);
for (let i = 0; i < batchConfigs.length; i += chunk) {
  await lifecycle.spawnBatch(batchConfigs.slice(i, i + chunk));
}

Try / catch

try {
  await lifecycle.spawnBatch(configs);
} catch (e) {
  if (e instanceof Error && e.message.includes('maximum concurrent agents')) {
    // free capacity (terminate finished agents), then spawn in smaller chunks
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling spawnBatch(configs) while the pool already holds agents, e.g. maxConcurrentAgents: 10 with 8 live agents and a batch of 5 (8 + 5 > 10). Also hit when finished agents are never terminate()d so the pool never drains, or when swarm-init code (e.g. a hierarchical topology spawning 5-15 agents) submits a bigger batch than the configured ceiling.

Common situations: Swarm recipes spawning many agents while LifecycleManagerConfig keeps a low maxConcurrentAgents default; scaling up --max-agents on the CLI without raising the lifecycle manager's ceiling; long-running orchestrators that spawn but never terminate agents.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/77103a7b3c2a31d0. Report an issue: GitHub.