{"record":{"id":"671bde8b62a8a4f4","repo":"paperclipai/paperclip","slug":"service-process-exited-before-binding-its-allocate","errorCode":null,"errorMessage":"service process exited before binding its allocated port","messagePattern":"service process exited before binding its allocated port","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/workspace-runtime.ts","lineNumber":4812,"sourceCode":"      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);\n      }\n      // Require the same launched process group to retain ownership across a stability delay.\n      // Cwd matching alone is insufficient because sibling services can share a workspace.\n      await delay(250);\n      if (input.child.exitCode !== null || input.child.signalCode !== null) {\n        throw new Error(\"service process exited after losing its allocated port\");\n      }\n      const stableOwnerPid = await readLocalServicePortOwner(input.port);\n      if (!stableOwnerPid || !(await isLocalServiceProcessOwnedBy(stableOwnerPid, childPid))) {\n        throw new RuntimeServicePortBindCollision(input.port);\n      }","sourceCodeStart":4794,"sourceCodeEnd":4830,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/services/workspace-runtime.ts#L4794-L4830","documentation":"waitForAllocatedPortBind detected the spawned service child process exited (exitCode or signalCode set) before it ever bound its allocated port. The service crashed during startup; the bind wait aborts with this cause.","triggerScenarios":"Thrown at server/src/services/workspace-runtime.ts:4659 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the service's stderr/logs to find why it exited, fix the startup failure, and restart it.","Ensure the service binds the allocated port rather than choosing its own or exiting early."],"exampleFix":null,"handlingStrategy":"try-catch","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"}