thedotmack/claude-mem · warning
Shutdown already in progress — ignoring re-entrant shutdown
Error message
Shutdown already in progress — ignoring re-entrant shutdown request
What it means
The shutdown sequence is guarded by a re-entrancy flag (WorkerService.isShuttingDown). A second shutdown request — another signal, a CLI stop, or a restart — arriving while a shutdown is already running logs this warning and returns immediately, so teardown steps cannot interleave or run twice.
Source
Thrown at src/services/worker-shutdown.ts:66
removePidFile: () => void;
spawnDaemon: (scriptPath: string, port: number) => number | undefined;
}
export interface ShutdownSequenceOptions {
reason: WorkerShutdownReason;
/** Reads the owner's shutdown flag (WorkerService.isShuttingDown). */
isShuttingDown: () => boolean;
markShuttingDown: () => void;
/** Pre-graceful bookkeeping: transcript watcher, heartbeat, sentinel, telemetry flush. */
beforeGracefulShutdown: () => Promise<void>;
performGracefulShutdown: () => Promise<void>;
gracefulDeadlineMs: number;
restartHandoff: RestartHandoffDeps;
}
export async function runShutdownSequence(options: ShutdownSequenceOptions): Promise<void> {
if (options.isShuttingDown()) {
logger.warn('SYSTEM', 'Shutdown already in progress — ignoring re-entrant shutdown request', {
reason: options.reason,
});
return;
}
options.markShuttingDown();
try {
await options.beforeGracefulShutdown();
} catch (error: unknown) {
// Pre-graceful bookkeeping (watcher/heartbeat/sentinel/telemetry flush)
// failing must not abort the sequence: graceful shutdown and — for
// restarts — the successor handoff still have to run. Same "proceed on
// error, never abort the handoff" policy as performGracefulShutdown below.
logger.error(
'SYSTEM',
'Pre-graceful shutdown bookkeeping failed — proceeding',
{ reason: options.reason },
error instanceof Error ? error : new Error(String(error))View on GitHub (pinned to e2d1df569a)
Solutions
- Treat it as benign — the first shutdown continues; just wait for process exit
- If the process never exits afterwards, the first shutdown is hung — inspect the graceful-shutdown deadline warning and hanging resources
- Configure supervisors to send one signal and wait (e.g. docker StopSignal + generous stop timeout)
Defensive patterns
Strategy: validation
Validate before calling
async function shutdownOnce(worker: WorkerService, reason: string): Promise<void> {
if (worker.isShuttingDown) return; // idempotent guard on the caller side too
await worker.shutdown(reason);
} Prevention
- Send a single shutdown signal and wait; suppress duplicate signals in wrappers
- Configure supervisors (docker/pm2/systemd) with adequate stop timeouts so the first signal can finish
- Treat the warning as confirmation the guard worked, not as a fault to fix
When it happens
Trigger: Pressing Ctrl+C twice; sending SIGTERM followed by SIGINT; running `claude-mem stop` while a supervisor-initiated shutdown is in flight; a restart racing a signal.
Common situations: Impatient double Ctrl+C in a terminal; process managers (systemd, pm2, docker stop) that send multiple signals; test harnesses that trigger shutdown from several code paths.
Related errors
- [uninstall] Worker shutdown attempt failed:
- Shutdown request returned error
- Port did not free up after shutdown
- Graceful shutdown deadline exceeded — proceeding
- Folder does not exist: ${folderPath}
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/26e796a229fc62c6.
Report an issue: GitHub.