ruvnet/ruflo · error · Error

Cannot start terminated agent

Error message

Cannot start terminated agent

What it means

Agent entity (DDD aggregate) enforces its lifecycle: terminate() moves the agent to 'terminated', which is a terminal state, and start() refuses to transition out of it. Once terminated, the agent cannot be reactivated — this throw is the state machine rejecting an invalid transition.

Source

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

  get updatedAt(): Date {
    return new Date(this._updatedAt);
  }

  get lastActiveAt(): Date {
    return new Date(this._lastActiveAt);
  }

  // ============================================================================
  // Business Logic Methods
  // ============================================================================

  /**
   * Start the agent (transition to active)
   */
  start(): void {
    if (this._status === 'terminated') {
      throw new Error('Cannot start terminated agent');
    }
    this._status = 'active';
    this._lastActiveAt = new Date();
    this._updatedAt = new Date();
  }

  /**
   * Pause the agent
   */
  pause(): void {
    if (this._status !== 'active' && this._status !== 'busy') {
      throw new Error('Can only pause active or busy agent');
    }
    this._status = 'paused';
    this._updatedAt = new Date();
  }

  /**

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Check agent.status !== 'terminated' (the getter is public) before calling start()
  2. If work must continue, create a NEW agent instead of restarting a terminated one — termination is final
  3. Filter terminated agents out of any recovery/restart loops
  4. If the agent should have been idle rather than terminated, fix the earlier code path that called terminate()

Example fix

// before
agents.forEach(a => a.start()); // throws for terminated agents

// after
agents.filter(a => a.status !== 'terminated').forEach(a => a.start());
Defensive patterns

Strategy: type-guard

Validate before calling

if (agent.status === 'terminated') {
  agent = spawnReplacementAgent(agent); // termination is final — never call start()
}
agent.start();

Type guard

const canStart = (a) => a.status !== 'terminated';
// 'idle' | 'paused' | 'error' | 'active' | 'busy' -> start() legal; 'terminated' -> not
if (canStart(agent)) agent.start();

Try / catch

try { agent.start(); }
catch (e) {
  if (e instanceof Error && e.message === 'Cannot start terminated agent') {
    agent = createAgent(config); agent.start(); return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling agent.start() after agent.terminate() was invoked (directly or via a coordinator shutting the swarm down) Restart logic that iterates all agents calling start() without filtering out terminated ones Rehydrating an agent from persistence with status 'terminated' and running it through an activation routine

Common situations: Swarm scale-down followed by a generic 'reactivate all' routine Scheduler retry passes that don't check agent.status ORM/event-sourcing replay reaching a start() after a terminate() event

Related errors


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