{"record":{"id":"a072863b714f2c2d","repo":"ruvnet/ruflo","slug":"cannot-start-terminated-agent","errorCode":null,"errorMessage":"Cannot start terminated agent","messagePattern":"Cannot start terminated agent","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/swarm/src/domain/entities/agent.ts","lineNumber":182,"sourceCode":"\n  get updatedAt(): Date {\n    return new Date(this._updatedAt);\n  }\n\n  get lastActiveAt(): Date {\n    return new Date(this._lastActiveAt);\n  }\n\n  // ============================================================================\n  // Business Logic Methods\n  // ============================================================================\n\n  /**\n   * Start the agent (transition to active)\n   */\n  start(): void {\n    if (this._status === 'terminated') {\n      throw new Error('Cannot start terminated agent');\n    }\n    this._status = 'active';\n    this._lastActiveAt = new Date();\n    this._updatedAt = new Date();\n  }\n\n  /**\n   * Pause the agent\n   */\n  pause(): void {\n    if (this._status !== 'active' && this._status !== 'busy') {\n      throw new Error('Can only pause active or busy agent');\n    }\n    this._status = 'paused';\n    this._updatedAt = new Date();\n  }\n\n  /**","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/swarm/src/domain/entities/agent.ts#L164-L200","documentation":"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.","triggerScenarios":"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","commonSituations":"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","solutions":["Check agent.status !== 'terminated' (the getter is public) before calling start()","If work must continue, create a NEW agent instead of restarting a terminated one — termination is final","Filter terminated agents out of any recovery/restart loops","If the agent should have been idle rather than terminated, fix the earlier code path that called terminate()"],"exampleFix":"// before\nagents.forEach(a => a.start()); // throws for terminated agents\n\n// after\nagents.filter(a => a.status !== 'terminated').forEach(a => a.start());","handlingStrategy":"type-guard","validationCode":"if (agent.status === 'terminated') {\n  agent = spawnReplacementAgent(agent); // termination is final — never call start()\n}\nagent.start();","typeGuard":"const canStart = (a) => a.status !== 'terminated';\n// 'idle' | 'paused' | 'error' | 'active' | 'busy' -> start() legal; 'terminated' -> not\nif (canStart(agent)) agent.start();","tryCatchPattern":"try { agent.start(); }\ncatch (e) {\n  if (e instanceof Error && e.message === 'Cannot start terminated agent') {\n    agent = createAgent(config); agent.start(); return;\n  }\n  throw e;\n}","preventionTips":["Filter terminated agents out of every restart/recovery routine","Model 'terminated' as final in your coordinator: remove from pools on terminate()","Prefer spawn-a-new-agent over any 'revive' logic"],"tags":["agent","state-machine","lifecycle","domain-entity","typescript"],"backgroundTag":"state-machine-invalid-transition","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}