thedotmack/claude-mem · warning

Live PID detected but worker did not become ready before…

Error message

Live PID detected but worker did not become ready before timeout

What it means

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.

Solutions

  1. Wait and retry — the worker may finish warming and become ready
  2. Check worker logs for boot errors or hangs during initialization
  3. Kill the stuck process (delete pid file) and trigger a fresh spawn
  4. Verify CLI and worker versions match (version is logged on verified handoff)

Example fix

// before
const status = await ensureWorkerStarted(port);
if (status === 'warming') throw new Error('worker not ready');
// after
let status = await ensureWorkerStarted(port);
if (status === 'warming') {
  await sleep(2000);
  status = await ensureWorkerStarted(port); // retry once after warming
}
Defensive patterns

Strategy: retry

Validate before calling

const pidAlive = cleanStalePidFile() === 'alive';
if (pidAlive) console.log('worker pid alive; allow extra readiness time before retry');

Try / catch

async function waitUntilReady(port, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    const s = await ensureWorkerStarted(port);
    if (s === 'ready') return true;
    await sleep(2000);
  }
  return false;
}

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

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


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/08088a7293c48048. Report an issue: GitHub.

Appendix: source

Thrown at src/services/worker-spawner.ts:119

    return 'dead';
  }

  const pidFileStatus = cleanStalePidFile();
  if (pidFileStatus === 'alive') {
    logger.info('SYSTEM', 'Worker PID file points to a live process, skipping duplicate spawn');
    const ready = await waitForReadiness(port, getPlatformTimeout(HOOK_TIMEOUTS.READINESS_WAIT));
    if (ready) {
      clearWorkerSpawnAttempted();
      logger.info('SYSTEM', 'Worker became ready while waiting on live PID');
      return 'ready';
    }
    const workerStillHealthy = await waitForHealth(port, 1000);
    const workerPidStillAlive = cleanStalePidFile() === 'alive';
    if (!workerStillHealthy && !workerPidStillAlive) {
      logger.error('SYSTEM', 'Live PID disappeared before readiness endpoint became available');
      return 'dead';
    }
    logger.warn('SYSTEM', 'Live PID detected but worker did not become ready before timeout');
    return 'warming';
  }

  if (await waitForHealth(port, 1000)) {
    clearWorkerSpawnAttempted();
    const ready = await waitForReadiness(port, getPlatformTimeout(HOOK_TIMEOUTS.READINESS_WAIT));
    if (!ready) {
      logger.warn('SYSTEM', 'Worker is alive but readiness timed out — proceeding anyway');
    }
    logger.info('SYSTEM', 'Worker already running and healthy');
    return ready ? 'ready' : 'warming';
  }

  const portInUse = await isPortInUse(port);
  if (portInUse) {
    logger.info('SYSTEM', 'Port in use, waiting for worker to become healthy');
    const healthy = await waitForHealth(port, getPlatformTimeout(HOOK_TIMEOUTS.PORT_IN_USE_WAIT));
    if (healthy) {

View on GitHub (pinned to d8bc9755e7)