ruvnet/ruflo · error · Error

Pool ${this.config.name} is at maximum capacity

Error message

Pool ${this.config.name} is at maximum capacity

What it means

AgentPool caps the number of pooled agents at config.maxSize. add() throws when pooledAgents.size has already reached maxSize — the pool never silently grows past its configured bound. Slots become available again only through release(), which returns an agent to idle and may trigger scale-down via checkScaling().

Source

Thrown at v3/@claude-flow/swarm/src/agent-pool.ts:154

      return;
    }

    this.busy.delete(agentId);
    this.available.add(agentId);
    pooled.acquiredAt = undefined;
    pooled.lastUsed = new Date();
    pooled.agent.status = 'idle';
    pooled.agent.currentTask = undefined;

    this.emit('agent.released', { agentId });

    // Check if we need to scale down
    await this.checkScaling();
  }

  async add(agent: AgentState): Promise<void> {
    if (this.pooledAgents.size >= this.config.maxSize) {
      throw new Error(`Pool ${this.config.name} is at maximum capacity`);
    }

    const pooled: PooledAgent = {
      agent,
      lastUsed: new Date(),
      usageCount: 0,
    };

    this.pooledAgents.set(agent.id.id, pooled);
    this.available.add(agent.id.id);

    this.emit('agent.added', { agentId: agent.id.id });
  }

  async remove(agentId: string): Promise<void> {
    const pooled = this.pooledAgents.get(agentId);
    if (!pooled) {
      return;

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Release agents when their work finishes: call pool.release(agentId) in try/finally.
  2. Increase config.maxSize to match the maximum number of concurrent agents.
  3. Before add(), compare current pool occupancy against maxSize and drain idle agents first.
  4. Diagnose leaks: 'agent.added' events should be balanced by 'agent.released'; use lastUsed/usageCount stats to find holders.

Example fix

// before — agents added but never released; pool pins at maxSize
await pool.add(agent);
await runTask(agent);

// after — release in finally and size the cap for peak concurrency
const pool = new AgentPool({ name: 'workers', maxSize: peakConcurrency });
await pool.add(agent);
try {
  await runTask(agent);
} finally {
  await pool.release(agent.id.id);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// track occupancy yourself: every add must pair with a release
let inPool = 0;
await pool.add(agent); inPool++;
try {
  await runTask(agent);
} finally {
  await pool.release(agent.id.id);
  inPool--;
}
// check inPool < config.maxSize before the next add

Try / catch

try {
  await pool.add(agent);
} catch (e) {
  if (e instanceof Error && e.message.endsWith('is at maximum capacity')) {
    await drainIdleOrWaitForRelease(); // or rebuild the pool with a larger maxSize
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling add() while the pool already holds maxSize agents; agents acquired for work but never release()d (leak); an auto-scaler spawning new agents into a full pool; maxSize configured below the number of concurrently needed agents.

Common situations: Missing release() in a finally block after task execution; long-lived idle agents occupying slots; pool sizing never revisited after traffic grew; scale-up loop ignoring pool capacity.

Related errors


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