paperclipai/paperclip · error

Readiness check failed for ${readinessUrl}: ${lastError}

Error message

Readiness check failed for ${readinessUrl}: ${lastError}

What it means

The HTTP readiness probe loop exhausted its timeout while the service never returned an acceptable response; the last per-probe error (connection refused, non-2xx status, abort) is included. The service did not become healthy in time.

Source

Thrown at server/src/services/workspace-runtime.ts:4801

  const fetchImpl = input.fetchImpl ?? fetch;
  const now = input.now ?? Date.now;
  const timeoutSec = resolveWorkspaceRuntimeReadinessTimeoutSec(input.service);
  const intervalMs = Math.max(100, asNumber(readiness.intervalMs, 500));
  const deadline = now() + timeoutSec * 1000;
  let lastError = "service did not become ready";
  while (now() < deadline) {
    const probeBudgetMs = Math.max(1, Math.min(RUNTIME_SERVICE_READINESS_PROBE_TIMEOUT_MS, deadline - now()));
    try {
      const response = await fetchImpl(readinessUrl, { signal: AbortSignal.timeout(probeBudgetMs) });
      if (response.ok) return;
      lastError = `received HTTP ${response.status}`;
    } catch (err) {
      lastError = err instanceof Error ? err.message : String(err);
    }
    if (now() >= deadline) break;
    await delay(Math.min(intervalMs, Math.max(0, deadline - now())));
  }
  throw new Error(`Readiness check failed for ${readinessUrl}: ${lastError}`);
}

async function waitForAllocatedPortBind(input: {
  service: Record<string, unknown>;
  port: number;
  child: ChildProcess;
}) {
  const deadline = Date.now() + resolveWorkspaceRuntimeReadinessTimeoutSec(input.service) * 1000;
  while (Date.now() < deadline) {
    if (input.child.exitCode !== null || input.child.signalCode !== null) {
      throw new Error("service process exited before binding its allocated port");
    }

    const ownerPid = await readLocalServicePortOwner(input.port);
    if (ownerPid) {
      const childPid = input.child.pid ?? null;
      if (!childPid || !(await isLocalServiceProcessOwnedBy(ownerPid, childPid))) {
        throw new RuntimeServicePortBindCollision(input.port);

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Check lastError to see why the readiness probe failed, fix the service (listen address, health endpoint), and retry.
  2. Increase the readiness timeout if the service is slow to become healthy.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at server/src/services/workspace-runtime.ts:4648 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18). Data as JSON: /api/errors/6c46a2fddb3ba99c. Report an issue: GitHub.