{"record":{"id":"9ea2009d6401868f","repo":"thedotmack/claude-mem","slug":"supervisor-is-shutting-down-refusing-to-spawn-t","errorCode":null,"errorMessage":"Supervisor is shutting down, refusing to spawn ${type}","messagePattern":"Supervisor is shutting down, refusing to spawn (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/supervisor/index.ts","lineNumber":135,"sourceCode":"      await this.stopPromise;\n      return;\n    }\n\n    stopHealthChecker();\n    this.stopPromise = runShutdownCascade({\n      registry: this.registry,\n      currentPid: process.pid\n    }).finally(() => {\n      this.started = false;\n      this.stopPromise = null;\n    });\n\n    await this.stopPromise;\n  }\n\n  assertCanSpawn(type: string): void {\n    if (this.stopPromise !== null) {\n      throw new Error(`Supervisor is shutting down, refusing to spawn ${type}`);\n    }\n  }\n\n  registerProcess(id: string, processInfo: ManagedProcessInfo, processRef?: Parameters<ProcessRegistry['register']>[2]): void {\n    this.registry.register(id, processInfo, processRef);\n  }\n\n  unregisterProcess(id: string): void {\n    this.registry.unregister(id);\n  }\n\n  getRegistry(): ProcessRegistry {\n    return this.registry;\n  }\n}\n\nconst supervisorSingleton = new Supervisor(getProcessRegistry());\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/supervisor/index.ts#L117-L153","documentation":"assertCanSpawn is the supervisor's shutdown gate: once stop() has been initiated (stopPromise is non-null), no new managed processes may be spawned. Any component asking the supervisor to spawn a child during shutdown gets this error naming the process type. It prevents zombie children created while the supervisor is tearing down.","triggerScenarios":"Requesting a spawn of process `type` after supervisor.stop() was called but before shutdown completed (stopPromise still pending or just non-null).","commonSituations":"A request or session arriving concurrently with a shutdown/restart; background tasks that lazily spawn workers racing a SIGTERM; tests that stop a shared supervisor then trigger more work.","solutions":["Check supervisor state before requesting a spawn and skip/queue the work during shutdown","Retry the operation after the supervisor has restarted","Fix race conditions where shutdown and new work are triggered concurrently","Drain in-flight requests before calling stop()"],"exampleFix":"// before\nsupervisor.spawn('sdk-worker'); // may throw during shutdown\n// after\ntry {\n  supervisor.assertCanSpawn('sdk-worker');\n  supervisor.spawn('sdk-worker');\n} catch {\n  queueAfterRestart('sdk-worker');\n}","handlingStrategy":"try-catch","validationCode":"if (supervisor.isShuttingDown()) { deferWork(); } else { supervisor.spawn(type); }","typeGuard":null,"tryCatchPattern":"try { supervisor.assertCanSpawn(type); supervisor.spawn(type); }\ncatch { pendingSpawns.push(type); supervisor.on('started', () => flushPendingSpawns()); }","preventionTips":["Subscribe to supervisor shutdown events and pause producers of new work","Drain in-flight requests before calling stop()","Make spawn requests idempotent/retryable so a shutdown race is harmless"],"tags":["process","lifecycle","shutdown"],"backgroundTag":"invalid-state-transition","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}