ruvnet/ruflo · error · Error

Agent at maximum concurrent task capacity

Error message

Agent at maximum concurrent task capacity

What it means

assignTask() enforces maxConcurrentTasks: it throws when the size of the agent's current task-id set already equals the configured cap. The entity deliberately fails fast instead of queueing — overflow handling is the caller's responsibility.

Source

Thrown at v3/@claude-flow/swarm/src/domain/entities/agent.ts:253

   */
  recover(): void {
    if (this._status !== 'error') {
      throw new Error('Can only recover from error state');
    }
    this._status = 'idle';
    delete this._metadata['lastError'];
    this._updatedAt = new Date();
  }

  /**
   * Assign a task to this agent
   */
  assignTask(taskId: string): void {
    if (this._status === 'terminated') {
      throw new Error('Cannot assign task to terminated agent');
    }
    if (this._currentTaskIds.size >= this._maxConcurrentTasks) {
      throw new Error('Agent at maximum concurrent task capacity');
    }

    this._currentTaskIds.add(taskId);
    this._status = 'busy';
    this._lastActiveAt = new Date();
    this._updatedAt = new Date();
  }

  /**
   * Complete a task
   */
  completeTask(taskId: string): void {
    if (!this._currentTaskIds.has(taskId)) {
      throw new Error(`Task ${taskId} not assigned to this agent`);
    }

    this._currentTaskIds.delete(taskId);
    this._completedTaskCount++;

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Always pair assignment with completion: call completeTask(taskId) (or the task's fail path) in a finally so slots free up
  2. Check available capacity before assigning (see validation snippet) or expose canAcceptTask() in your layer
  3. Raise maxConcurrentTasks on agent creation to match the dispatcher's parallelism
  4. Scale horizontally: pick a different agent or spawn one when all are at capacity

Example fix

// before
agent.assignTask(task.id); // throws when full

// after
function tryAssign(agent, taskId) {
  if (agent.status === 'terminated') return false;
  if (agent.currentTaskCount >= agent.maxConcurrentTasks) return false; // or track via your repo
  agent.assignTask(taskId);
  return true;
}
// creation: new Agent(..., { maxConcurrentTasks: 8 }) to match dispatcher
Defensive patterns

Strategy: validation

Validate before calling

// Track assignments in the dispatcher and enforce the cap before calling the entity:
const inflight = dispatcher.countInflight(agent.id);
if (inflight >= agentMax) { agent = pickAnother() || spawnAgent(); }
agent.assignTask(taskId);

Try / catch

try { agent.assignTask(taskId); }
catch (e) {
  if (e instanceof Error && e.message === 'Agent at maximum concurrent task capacity') {
    return enqueueOrReassign(taskId); // backpressure: queue the task / pick another agent
  }
  throw e;
}

Prevention

When it happens

Trigger: Assigning N+1 tasks to an agent whose maxConcurrentTasks is N (default caps are small in this domain layer) Leaked task ids: completeTask()/fail paths never ran, so the set stays full (ghost tasks) Coordinator fan-out that ignores per-agent capacity when balancing maxConcurrentTasks configured to a lower value than the dispatcher's parallelism

Common situations: Static round-robin dispatchers hitting the cap before any task completes Tasks stuck in 'running' whose completion callback was lost, permanently consuming a slot Merging workloads that raised task counts without raising maxConcurrentTasks Tests creating agents with maxConcurrentTasks: 1 then assigning two tasks

Related errors


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