thedotmack/claude-mem · warning
Worker spawned but readiness endpoint not responding within
Error message
Worker spawned but readiness endpoint not responding within window
What it means
After this launcher spawned a worker, /readiness did not respond within the window (~30s platform-adjusted), but the health endpoint, PID file, or spawned process is still alive — so the worker did start, it is just not fully initialized. The spawner logs this (the spawn-lock-holder variant) and returns 'warming' instead of failing.
Source
Thrown at src/services/worker-spawner.ts:171
return 'dead';
}
} else {
logger.info('SYSTEM', 'Another launcher holds the spawn lock — skipping duplicate spawn and waiting for its worker');
}
const ready = await waitForReadiness(port, getPlatformTimeout(HOOK_TIMEOUTS.READINESS_WAIT));
if (!ready) {
const workerStillHealthy = await waitForHealth(port, 1000);
const workerPidStillAlive = cleanStalePidFile() === 'alive';
const spawnedProcessStillAlive = spawnedPid !== undefined && spawnedPid > 0 && isPidAlive(spawnedPid);
if (!workerStillHealthy && !workerPidStillAlive && !spawnedProcessStillAlive) {
logger.error('SYSTEM', spawnLockHeld
? 'Worker exited before readiness endpoint became available'
: 'Spawn-lock holder never produced a live worker before readiness timed out');
return 'dead';
}
logger.warn('SYSTEM', spawnLockHeld
? 'Worker spawned but readiness endpoint not responding within window'
: 'Spawn-lock holder\'s worker not ready within window');
return 'warming';
}
clearWorkerSpawnAttempted();
// touchPidFile is existsSync-guarded and merely refreshes the live worker's
// pid-file mtime — correct for lock losers too, since the worker IS up.
touchPidFile();
logger.info('SYSTEM', spawnLockHeld
? 'Worker started successfully'
: 'Worker is up (started by another launcher)');
return 'ready';
} finally {
if (spawnLockHeld) releaseSpawnLock();
}
}
View on GitHub (pinned to e2d1df569a)
Solutions
- Wait for readiness: poll GET /readiness or run `claude-mem status` again after a minute
- Check worker logs for which init step is slow or stuck (dependency preflight warnings appear above this one)
- If it happens on every start, trim the search index/backlog or extend the platform timeout
Defensive patterns
Strategy: retry
Validate before calling
async function waitReadyAfterSpawn(port: number, timeoutMs = 60000): Promise<boolean> {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
try { if (await fetch(`http://127.0.0.1:${port}/readiness`).then(r => r.ok)) return true; } catch {}
await new Promise(r => setTimeout(r, 1000));
}
return false;
} Prevention
- After spawning, wait on /readiness with your own (longer) budget instead of trusting one fixed window
- Do not spawn a second worker when the first is merely warming
- Warm the worker before hook-heavy sessions (start it at session begin)
When it happens
Trigger: Spawn succeeded but DB/search initialization exceeds READINESS_WAIT: first-run dependency setup, large migrations, or heavy load during startup.
Common situations: Cold starts after install or upgrade; machines with slow disks; concurrent claude-mem hooks triggering while init runs.
Related errors
- Live PID detected but worker did not become ready before tim
- Worker is healthy but not ready; skipping hook API call
- Worker port did not open after lazy-spawn within the cold-bo
- Worker lazy-spawned but did not become ready before hook rea
- [uninstall] Worker shutdown attempt failed:
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/9f3678ae83255d8b.
Report an issue: GitHub.