{"record":{"id":"08088a7293c48048","repo":"thedotmack/claude-mem","slug":"live-pid-detected-but-worker-did-not-become-ready","errorCode":null,"errorMessage":"Live PID detected but worker did not become ready before timeout","messagePattern":"Live PID detected but worker did not become ready before timeout","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/worker-spawner.ts","lineNumber":119,"sourceCode":"    return 'dead';\n  }\n\n  const pidFileStatus = cleanStalePidFile();\n  if (pidFileStatus === 'alive') {\n    logger.info('SYSTEM', 'Worker PID file points to a live process, skipping duplicate spawn');\n    const ready = await waitForReadiness(port, getPlatformTimeout(HOOK_TIMEOUTS.READINESS_WAIT));\n    if (ready) {\n      clearWorkerSpawnAttempted();\n      logger.info('SYSTEM', 'Worker became ready while waiting on live PID');\n      return 'ready';\n    }\n    const workerStillHealthy = await waitForHealth(port, 1000);\n    const workerPidStillAlive = cleanStalePidFile() === 'alive';\n    if (!workerStillHealthy && !workerPidStillAlive) {\n      logger.error('SYSTEM', 'Live PID disappeared before readiness endpoint became available');\n      return 'dead';\n    }\n    logger.warn('SYSTEM', 'Live PID detected but worker did not become ready before timeout');\n    return 'warming';\n  }\n\n  if (await waitForHealth(port, 1000)) {\n    clearWorkerSpawnAttempted();\n    const ready = await waitForReadiness(port, getPlatformTimeout(HOOK_TIMEOUTS.READINESS_WAIT));\n    if (!ready) {\n      logger.warn('SYSTEM', 'Worker is alive but readiness timed out — proceeding anyway');\n    }\n    logger.info('SYSTEM', 'Worker already running and healthy');\n    return ready ? 'ready' : 'warming';\n  }\n\n  const portInUse = await isPortInUse(port);\n  if (portInUse) {\n    logger.info('SYSTEM', 'Port in use, waiting for worker to become healthy');\n    const healthy = await waitForHealth(port, getPlatformTimeout(HOOK_TIMEOUTS.PORT_IN_USE_WAIT));\n    if (healthy) {","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/worker-spawner.ts#L101-L137","documentation":"ensureWorkerStarted detected a live PID (pid file says the process is alive) but the worker never served its readiness endpoint before the wait timed out. After a final health+PID recheck, it classifies the worker as 'warming' — alive but not yet usable — rather than dead.","triggerScenarios":"A worker process exists (cleanStalePidFile() === 'alive') but waitForReadiness timed out; a last-chance waitForHealth(port, 1000) also fails, yet the PID still lives, so the code logs this warning and returns 'warming'.","commonSituations":"Worker booted but is stuck initializing (slow Chroma/Python startup via uv); readiness route not yet registered during a version mismatch between CLI and worker; process alive but wedged; slow cold start on Windows.","solutions":["Wait and retry — the worker may finish warming and become ready","Check worker logs for boot errors or hangs during initialization","Kill the stuck process (delete pid file) and trigger a fresh spawn","Verify CLI and worker versions match (version is logged on verified handoff)"],"exampleFix":"// before\nconst status = await ensureWorkerStarted(port);\nif (status === 'warming') throw new Error('worker not ready');\n// after\nlet status = await ensureWorkerStarted(port);\nif (status === 'warming') {\n  await sleep(2000);\n  status = await ensureWorkerStarted(port); // retry once after warming\n}","handlingStrategy":"retry","validationCode":"const pidAlive = cleanStalePidFile() === 'alive';\nif (pidAlive) console.log('worker pid alive; allow extra readiness time before retry');","typeGuard":null,"tryCatchPattern":"async function waitUntilReady(port, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    const s = await ensureWorkerStarted(port);\n    if (s === 'ready') return true;\n    await sleep(2000);\n  }\n  return false;\n}","preventionTips":["Retry with backoff when status is 'warming'","Pre-warm the worker before latency-sensitive operations","Check worker logs when readiness repeatedly times out","Delete stale pid files before forced respawns"],"tags":["worker","readiness","timeout","startup"],"backgroundTag":"request-timeout","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}