thedotmack/claude-mem · warning

Worker is alive but readiness timed out — proceeding anyway

Error message

Worker is alive but readiness timed out — proceeding anyway

What it means

The worker is already running and passes the health check, but its readiness endpoint did not respond within READINESS_WAIT. The spawner treats this as non-fatal: it logs 'Worker already running and healthy' and returns 'warming' so callers can proceed or retry later.

Solutions

  1. Treat 'warming' as acceptable and retry the request shortly
  2. Restart the worker so versions align (CLI restart / delete pid file)
  3. Increase READINESS_WAIT timeout on slow machines
  4. Confirm worker version matches the CLI to ensure the readiness route exists

Example fix

// before
const status = await ensureWorkerStarted(port);
if (status !== 'ready') return;
// after
const status = await ensureWorkerStarted(port);
if (status === 'warming') return; // health OK; readiness will follow — proceed optimistically
Defensive patterns

Strategy: retry

Validate before calling

const healthy = await waitForHealth(port, 1000);
if (!healthy) throw new Error('worker not healthy at all'); // distinct from warming
const ready = await fetch(`http://localhost:${port}/readiness`).then(r => r.ok).catch(() => false);

Try / catch

const status = await ensureWorkerStarted(port);
if (status === 'warming') {
  // health passed; poll readiness a bit longer before giving up
  const ready = await waitForReadiness(port, 5000);
}

Prevention

When it happens

Trigger: waitForHealth(port, 1000) succeeds (worker up) but waitForReadiness(port, getPlatformTimeout(READINESS_WAIT)) returns false — readiness endpoint slow, not yet implemented, or the worker is up but still loading models/session state.

Common situations: Version skew: older worker binary lacking the readiness route while health exists; heavy init (Chroma startup) delaying readiness; transient network/socket hiccup on localhost; very short platform timeout.

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/d757c23e941c8e8f. Report an issue: GitHub.

Appendix: source

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

      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) {
      clearWorkerSpawnAttempted();
      const ready = await waitForReadiness(port, getPlatformTimeout(HOOK_TIMEOUTS.READINESS_WAIT));
      logger.info('SYSTEM', 'Worker is now healthy');
      return ready ? 'ready' : 'warming';
    }
    // The port is bound but nothing answers health. Usually this is a dead
    // worker whose surviving chroma sidecar chain (uvx -> uv -> python) holds
    // the inherited listening socket — a ghost listener under a dead PID

View on GitHub (pinned to d8bc9755e7)