thedotmack/claude-mem · warning
Worker service did not confirm shutdown; continuing…
Error message
Worker service did not confirm shutdown; continuing uninstall cleanup.
What it means
During uninstall, claude-mem asks the background worker to shut down via shutdownWorkerAndWait and only proceeds to clean up settings once the worker has confirmed it stopped (health probe returns ECONNREFUSED). This warning is emitted when a worker was detected as running but never confirmed shutdown within the 10s budget, meaning an in-memory worker may still be alive while the uninstaller continues removing files/settings. It exists because the installer deliberately fails closed rather than corrupting state under a live worker.
Solutions
- Check if a claude-mem worker is still listening on CLAUDE_MEM_WORKER_PORT (curl http://127.0.0.1:<port>/api/health) and kill it manually, then re-run uninstall
- Restart the machine or kill stale bun/worker processes to release the port
- Increase the shutdown timeout and retry uninstall after fixing whatever is blocking the worker
- Re-run the uninstall after the worker has exited; settings cleanup will then proceed safely
Example fix
// before: uninstall proceeds with live worker
const result = await shutdownWorkerAndWait(workerPort, 10000);
// after: fail fast and instruct the user
const result = await shutdownWorkerAndWait(workerPort, 10000);
if (result.workerWasRunning && !result.stopped) {
p.log.error(`Worker on port ${workerPort} did not stop. Kill it and re-run uninstall.`);
process.exit(1);
} Defensive patterns
Strategy: retry
Validate before calling
const res = await fetch(`http://127.0.0.1:${port}/api/health`, { signal: AbortSignal.timeout(1000) });
const workerLive = res.ok; // if true, ensure shutdown completes before uninstall Type guard
function shutdownConfirmed(r: { workerWasRunning: boolean; stopped: boolean }): boolean {
return !r.workerWasRunning || r.stopped;
} Try / catch
const result = await shutdownWorkerAndWait(port, 10000);
if (result.workerWasRunning && !result.stopped) {
console.warn('Worker still live; aborting uninstall to avoid corrupting settings.');
return;
} Prevention
- Probe /api/health before uninstalling to know a worker is live
- Kill stale bun/worker processes or reboot before uninstalling
- Do not hand-edit claude-mem settings while a worker may be running
- Check CLAUDE_MEM_WORKER_PORT for squatters before install/uninstall
When it happens
Trigger: Worker POST /api/admin/shutdown times out or returns non-OK; the health probe after shutdown returns anything other than a connection refused (reset, timeout, protocol error) within the 10s window.
Common situations: Worker process hung or deadlocked; worker busy on a long task; port occupied by another process that answers health checks; slow machine where 10s teardown is insufficient.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- Graceful shutdown deadline exceeded — proceeding
- [uninstall] Worker shutdown attempt failed:
- Worker shutdown attempt failed
- Live PID detected but worker did not become ready before…
- Request timed out after
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/09eae8a79e32e8e1.
Report an issue: GitHub.
Appendix: source
Thrown at src/npx-cli/commands/uninstall.ts:277
} else if (process.stdin.isTTY) {
const shouldContinue = await p.confirm({
message: 'Are you sure you want to uninstall claude-mem?',
initialValue: false,
});
if (p.isCancel(shouldContinue) || !shouldContinue) {
p.cancel('Uninstall cancelled.');
return;
}
}
const workerPort = SettingsDefaultsManager.get('CLAUDE_MEM_WORKER_PORT');
try {
const result = await shutdownWorkerAndWait(workerPort, 10000);
if (result.workerWasRunning && result.stopped) {
p.log.info('Worker service stopped.');
} else if (result.workerWasRunning) {
p.log.warn('Worker service did not confirm shutdown; continuing uninstall cleanup.');
}
} catch (error: unknown) {
console.warn('[uninstall] Worker shutdown attempt failed:', error instanceof Error ? error.message : String(error));
}
// #2568 — server-runtime teardown. Gated on the installed/selected runtime so
// the worker uninstall path is completely unchanged. The bundled Docker
// compose stack lives under the marketplace dir; if it's present we treat the
// stack as locally managed and instruct teardown (the actual `docker compose
// down -v` is an operator/CI side effect, not run from this Node process).
const selectedRuntime = readSelectedRuntime();
if (selectedRuntime === 'server') {
if (existsSync(join(marketplaceDirectory(), 'docker-compose.yml'))) {
p.log.info(
'Server runtime detected. Tear down the bundled stack with '
+ '`docker compose down -v --remove-orphans` (stops + removes pg + redis/valkey).',
);
} else {View on GitHub (pinned to d8bc9755e7)