thedotmack/claude-mem · info
Shutdown already in progress — ignoring re-entrant shutdown…
Error message
Shutdown already in progress — ignoring re-entrant shutdown request
What it means
runShutdownSequence guards against re-entrancy: if a shutdown is already in flight (flag set via markShuttingDown), a second shutdown request is logged and ignored. This prevents double-exit races, duplicate handoff attempts, and conflicting cleanup.
Solutions
- No action needed — the first shutdown continues to completion
- Avoid sending duplicate signals; use a single SIGTERM and wait for exit
- If shutdown seems stuck, inspect logs for the in-flight shutdown's reason and deadline
Defensive patterns
Strategy: validation
Validate before calling
if (isShuttingDown()) {
console.log('shutdown already in progress; skipping duplicate request');
return;
} Try / catch
// Idempotent shutdown wrapper
async function shutdownOnce(reason) {
if (shuttingDown) return;
shuttingDown = true;
await runShutdownSequence({ reason, ... });
} Prevention
- Make signal handlers idempotent
- Guard shutdown entry points with a single boolean flag
- Debounce repeated SIGINT/SIGTERM before invoking shutdown
When it happens
Trigger: shutdown() is invoked twice — e.g. SIGINT delivered twice, SIGTERM arriving during an in-progress restart handoff, or both an explicit restart request and an OS signal triggering shutdown concurrently.
Common situations: User presses Ctrl-C repeatedly while a restart handoff is verifying; container orchestrator sends SIGTERM followed by a second signal; systemd stop overlapping with an in-app restart call.
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
- Graceful shutdown deadline exceeded — proceeding
- Shutdown request returned error
- [uninstall] Worker shutdown attempt failed:
- Worker service did not confirm shutdown; continuing…
- Worker shutdown attempt failed
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/26e796a229fc62c6.
Report an issue: GitHub.
Appendix: 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 d8bc9755e7)