{"record":{"id":"6c46a2fddb3ba99c","repo":"paperclipai/paperclip","slug":"readiness-check-failed-for-readinessurl-last","errorCode":null,"errorMessage":"Readiness check failed for ${readinessUrl}: ${lastError}","messagePattern":"Readiness check failed for (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/workspace-runtime.ts","lineNumber":4801,"sourceCode":"  const fetchImpl = input.fetchImpl ?? fetch;\n  const now = input.now ?? Date.now;\n  const timeoutSec = resolveWorkspaceRuntimeReadinessTimeoutSec(input.service);\n  const intervalMs = Math.max(100, asNumber(readiness.intervalMs, 500));\n  const deadline = now() + timeoutSec * 1000;\n  let lastError = \"service did not become ready\";\n  while (now() < deadline) {\n    const probeBudgetMs = Math.max(1, Math.min(RUNTIME_SERVICE_READINESS_PROBE_TIMEOUT_MS, deadline - now()));\n    try {\n      const response = await fetchImpl(readinessUrl, { signal: AbortSignal.timeout(probeBudgetMs) });\n      if (response.ok) return;\n      lastError = `received HTTP ${response.status}`;\n    } catch (err) {\n      lastError = err instanceof Error ? err.message : String(err);\n    }\n    if (now() >= deadline) break;\n    await delay(Math.min(intervalMs, Math.max(0, deadline - now())));\n  }\n  throw new Error(`Readiness check failed for ${readinessUrl}: ${lastError}`);\n}\n\nasync function waitForAllocatedPortBind(input: {\n  service: Record<string, unknown>;\n  port: number;\n  child: ChildProcess;\n}) {\n  const deadline = Date.now() + resolveWorkspaceRuntimeReadinessTimeoutSec(input.service) * 1000;\n  while (Date.now() < deadline) {\n    if (input.child.exitCode !== null || input.child.signalCode !== null) {\n      throw new Error(\"service process exited before binding its allocated port\");\n    }\n\n    const ownerPid = await readLocalServicePortOwner(input.port);\n    if (ownerPid) {\n      const childPid = input.child.pid ?? null;\n      if (!childPid || !(await isLocalServiceProcessOwnedBy(ownerPid, childPid))) {\n        throw new RuntimeServicePortBindCollision(input.port);","sourceCodeStart":4783,"sourceCodeEnd":4819,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/services/workspace-runtime.ts#L4783-L4819","documentation":"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.","triggerScenarios":"Thrown at server/src/services/workspace-runtime.ts:4648 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check lastError to see why the readiness probe failed, fix the service (listen address, health endpoint), and retry.","Increase the readiness timeout if the service is slow to become healthy."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}