thedotmack/claude-mem · error · Error
Supervisor is shutting down, refusing to spawn
Error message
Supervisor is shutting down, refusing to spawn ${type} What it means
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.
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()
Example fix
// before
supervisor.spawn('sdk-worker'); // may throw during shutdown
// after
try {
supervisor.assertCanSpawn('sdk-worker');
supervisor.spawn('sdk-worker');
} catch {
queueAfterRestart('sdk-worker');
} Defensive patterns
Strategy: try-catch
Validate before calling
if (supervisor.isShuttingDown()) { deferWork(); } else { supervisor.spawn(type); } Try / catch
try { supervisor.assertCanSpawn(type); supervisor.spawn(type); }
catch { pendingSpawns.push(type); supervisor.on('started', () => flushPendingSpawns()); } Prevention
- 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
When it happens
Trigger: Requesting a spawn of process `type` after supervisor.stop() was called but before shutdown completed (stopPromise still pending or just non-null).
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Local Chroma mutations are unavailable after shutdown begins
- chroma-mcp call cancelled during shutdown
- chroma-mcp connection cancelled during shutdown
- cloud sync must be configured before queueDelete
- Corpus " " has no session — call prime first
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/9ea2009d6401868f.
Report an issue: GitHub.
Appendix: source
Thrown at src/supervisor/index.ts:135
await this.stopPromise;
return;
}
stopHealthChecker();
this.stopPromise = runShutdownCascade({
registry: this.registry,
currentPid: process.pid
}).finally(() => {
this.started = false;
this.stopPromise = null;
});
await this.stopPromise;
}
assertCanSpawn(type: string): void {
if (this.stopPromise !== null) {
throw new Error(`Supervisor is shutting down, refusing to spawn ${type}`);
}
}
registerProcess(id: string, processInfo: ManagedProcessInfo, processRef?: Parameters<ProcessRegistry['register']>[2]): void {
this.registry.register(id, processInfo, processRef);
}
unregisterProcess(id: string): void {
this.registry.unregister(id);
}
getRegistry(): ProcessRegistry {
return this.registry;
}
}
const supervisorSingleton = new Supervisor(getProcessRegistry());
View on GitHub (pinned to d8bc9755e7)