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 spawner found the worker already running and healthy (/health responds), but /readiness did not pass within the wait window. It logs this warning, returns 'warming', and proceeds — the worker serves basic health while DB/search initialization is still finishing in the background.

Source

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

      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';
    }
    logger.error('SYSTEM', 'Port in use but worker not responding to health checks');
    return 'dead';
  }

View on GitHub (pinned to e2d1df569a)

Solutions

  1. Switch readiness checks from /health to /readiness before invoking memory-dependent features
  2. Retry the memory-dependent call after a short wait — 'warming' transitions to ready without intervention
  3. If permanently warming, inspect logs for init errors (dependency preflight, Chroma startup)

Example fix

// before
const ok = await fetch(`${base}/health`).then(r => r.ok);

// after
const ok = await fetch(`${base}/readiness`).then(r => r.ok);
Defensive patterns

Strategy: retry

Validate before calling

async function isReady(base: string): Promise<boolean> {
  try { return await fetch(`${base}/readiness`).then(r => r.ok); } catch { return false; }
}

Prevention

When it happens

Trigger: Calling a hook or MCP tool during the init tail: health endpoint is up (server listening) but the search routes are not registered yet.

Common situations: Hooks firing immediately after `claude-mem start`; automation that polls /health and assumes full readiness; slow disks delaying index load.

Understand the failure class

Related errors


AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20). Data as JSON: /api/errors/d757c23e941c8e8f. Report an issue: GitHub.