thedotmack/claude-mem · warning
Worker failed to start before hook, handler will proceed gra
Error message
Worker failed to start before hook, handler will proceed gracefully
What it means
Before dispatching a hook event (context, observation, summarize, ...), the hook command calls ensureWorkerStarted(). If that returns 'dead' — spawn failed, Windows cooldown skip, or port conflict without health — this warning fires. The hook then proceeds without the worker, so this event's memory capture is skipped rather than blocking the user's session.
Source
Thrown at src/services/worker-service.ts:1332
case 'hook': {
// IO discipline: this case is the entry point to the hook execution path.
// Once hookCommand is invoked, src/shared/hook-io.ts owns all
// stdout/stderr/exit. The pre-hookCommand error paths below (missing args,
// worker failed to start) are CLI-style: console.error + exit 1 is
// acceptable because they occur BEFORE the buffered window opens.
const platform = process.argv[3];
const event = process.argv[4];
if (!platform || !event) {
console.error('Usage: claude-mem hook <platform> <event>');
console.error('Platforms: claude-code, codex, cursor, antigravity-cli, raw');
console.error('Events: context, session-init, observation, summarize, user-message');
process.exit(1);
}
const workerStartResult = await ensureWorkerStarted(port);
if (workerStartResult === 'dead') {
logger.warn('SYSTEM', 'Worker failed to start before hook, handler will proceed gracefully');
}
const { hookCommand } = await import('../cli/hook-command.js');
await hookCommand(platform, event);
break;
}
case 'generate': {
const dryRun = process.argv.includes('--dry-run');
const { generateClaudeMd } = await import('../cli/claude-md-commands.js');
const result = await generateClaudeMd(dryRun);
process.exit(result);
break;
}
case 'clean': {
const dryRun = process.argv.includes('--dry-run');
const { cleanClaudeMd } = await import('../cli/claude-md-commands.js');View on GitHub (pinned to e2d1df569a)
Solutions
- Run `claude-mem start` manually and read the worker log to see the actual spawn failure
- On Windows, wait out the 2-minute spawn cooldown before retrying (or delete the cooldown marker once the root cause is fixed)
- Free the occupied port or move claude-mem to another one, then retry the hook-triggering action
Defensive patterns
Strategy: fallback
Validate before calling
const result = await ensureWorkerStarted(port);
if (result === 'dead') {
// proceed without worker; schedule a manual start instead of retrying in the hot path
console.warn('worker unavailable — hook will run without memory capture');
} Prevention
- Design hooks to degrade gracefully — never block the user's session on worker availability
- Start the worker at boot/session start so hooks do not lazy-spawn under pressure
- On Windows, fix the root spawn failure instead of hammering hooks inside the cooldown
When it happens
Trigger: Worker spawn fails (missing runtime, permissions, antivirus on Windows); shouldSkipSpawnOnWindows() suppresses spawn within the 2-minute cooldown after a prior failure; port occupied by a non-worker process.
Common situations: Windows machines where a previous spawn failed and hooks keep firing inside the cooldown; broken node/bun install; corporate security software blocking the daemon; disk-full preventing log/db writes at startup.
Related errors
- Self-replacing worker handoff did not verify in time — falli
- Worker unavailable on Windows — skipping spawn (recent attem
- Worker spawned but readiness endpoint not responding within
- Worker port did not open after lazy-spawn within the cold-bo
- uv installation completed but binary not found. Please resta
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/31fac0b4192089a9.
Report an issue: GitHub.