{"record":{"id":"1128abbc83f5f036","repo":"thedotmack/claude-mem","slug":"spawn-lock-holder-s-worker-port-did-not-open-withi","errorCode":null,"errorMessage":"Spawn-lock holder's worker port did not open within the cold-boot wait (~15s)","messagePattern":"Spawn-lock holder's worker port did not open within the cold-boot wait \\(~15s\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/shared/worker-utils.ts","lineNumber":596,"sourceCode":"        }\n        return false;\n      }\n    } else {\n      logger.info('SYSTEM', 'Another launcher holds the spawn lock — skipping lazy-spawn and waiting for its worker');\n    }\n\n    // Cold boot (#2795): on the first session after a reboot the SessionStart\n    // `start` hook is booting the daemon in parallel, and a cold macOS+Chroma\n    // worker needs ~7s to bind. The old 3-attempt/250ms budget (~0.75s) expired\n    // long before that, so the context (and session-init) hooks raced boot and\n    // soft-failed to empty — dropping memory injection and the user_prompts row\n    // (the upstream trigger for #2794). Wait up to ~15.5s (≈ POST_SPAWN_WAIT) so\n    // whichever worker wins the port is seen before we give up.\n    const alive = await waitForWorkerPort({ attempts: 6, backoffMs: 500 });\n    if (!alive) {\n      logger.warn('SYSTEM', spawnLockHeld\n        ? 'Worker port did not open after lazy-spawn within the cold-boot wait (~15s)'\n        : 'Spawn-lock holder\\'s worker port did not open within the cold-boot wait (~15s)');\n      return false;\n    }\n  } finally {\n    if (spawnLockHeld) releaseSpawnLock();\n  }\n  const ready = await waitForWorkerReadiness();\n  if (!ready) {\n    logger.warn('SYSTEM', 'Worker lazy-spawned but did not become ready before hook readiness timeout');\n    return false;\n  }\n  // Amplifier guard: even if the worker that won the port is still stale,\n  // never recycle a second time in the same hook invocation.\n  if (expectedPluginVersion !== null) {\n    await warnIfVersionStillMismatched(expectedPluginVersion);\n  }\n  return true;\n}\n","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/shared/worker-utils.ts#L578-L614","documentation":"Same cold-boot port wait, but this invocation lost the spawn gate (spawnLockHeld false): another gated launcher won and spawned, and this one waited on the winner's worker. The port still never opened within ~15s, so this hook also returns false. The spawn gate means exactly one spawner exists; losers just poll the shared port.","triggerScenarios":"Multiple hooks (start + context) race a cold boot; the spawn-gate winner's worker fails to bind (crash, slow init, port conflict) while all losers block on the same port-open wait and time out together.","commonSituations":"Several Claude sessions opened simultaneously after reboot; winner's spawn failing for environment reasons (missing env, corrupted DB) so every waiter fails.","solutions":["Triage identically to the winner-side failure: run the worker manually to surface the pre-bind error.","Check the worker port for conflicts and clear stale pid/lock files under ~/.claude-mem.","The next hook event re-enters the full spawn path — verify it succeeds there before debugging further.","Serialize cold boot by pre-warming the daemon at login."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// loser path: don't spawn, just wait for the winner's port\nconst alive = await waitForWorkerPort({ attempts: 6, backoffMs: 500 });\nif (!alive) return false; // next hook event re-enters the full spawn path","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid opening many Claude sessions simultaneously right after reboot — serialize the first session.","Pre-warm the daemon at login so spawn-gate winners and losers alike find a bound port.","If this repeats, debug the winner's spawn (run the worker manually) — losers only mirror its failure."],"tags":["worker","spawn-lock","port-open","timeout","claude-mem"],"backgroundTag":"startup-timeout","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}