{"record":{"id":"79433eb6a47efd54","repo":"paperclipai/paperclip","slug":"failed-to-start-worktree-port-reservation-lock-pro","errorCode":null,"errorMessage":"Failed to start worktree port reservation lock probe at ${lockPath}","messagePattern":"Failed to start worktree port reservation lock probe at (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/worktree-port-registry.ts","lineNumber":285,"sourceCode":"      heartbeatMs: WORKTREE_PORT_REGISTRY_LOCK_HEARTBEAT_MS,\n      lockPath,\n      ownerFiles: [\n        WORKTREE_PORT_REGISTRY_LOCK_OWNER_FILE,\n        WORKTREE_PORT_REGISTRY_LOCK_OWNER_BACKUP_FILE,\n      ],\n      probeTimeoutMs: WORKTREE_PORT_REGISTRY_LOCK_PROBE_TIMEOUT_MS,\n      token,\n    },\n  });\n  Atomics.wait(control, 0, 0, 2_000);\n  if (Atomics.load(control, 0) !== 1) {\n    void worker.terminate();\n    throw new Error(`Failed to start worktree port reservation lock heartbeat at ${lockPath}`);\n  }\n  const probePort = Atomics.load(control, 2);\n  if (probePort <= 0) {\n    void worker.terminate();\n    throw new Error(`Failed to start worktree port reservation lock probe at ${lockPath}`);\n  }\n  return { token, worker, control, probePort };\n}\n\nfunction stopRegistryLockHeartbeat(lease: RegistryLockLease): void {\n  Atomics.store(lease.control, 1, 1);\n  Atomics.notify(lease.control, 1);\n  lease.worker.postMessage(\"stop\");\n  if (Atomics.load(lease.control, 0) === 1) {\n    Atomics.wait(lease.control, 0, 1, 2_000);\n  }\n  void lease.worker.terminate();\n}\n\nfunction acquireRegistryLock(lockPath: string, deadline: number): RegistryLockLease | null {\n  try {\n    fs.mkdirSync(lockPath);\n    const token = `${process.pid}-${randomUUID()}`;","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/packages/shared/src/worktree-port-registry.ts#L267-L303","documentation":"Thrown by startRegistryLockHeartbeat when the heartbeat worker started (flag 1 set) but the probe port it reports is <= 0. The worker binds a TCP probe port that other processes use to verify the lock owner is truly alive; a worker that cannot bind reports no port, and the lock cannot be advertised, so acquisition aborts and cleans up.","triggerScenarios":"The worker's server.listen on an ephemeral port fails (EADDRNOTAVAIL, EACCES on restricted networks) or the listen callback never fires within the 2s readiness wait, leaving control[2] at 0; withWorktreePortRegistryLockSync then throws during lock acquisition.","commonSituations":"Containers/network namespaces with loopback binding restricted or no IPv4 stack ready; firewall or seccomp policies blocking socket creation; FD exhaustion (EMFILE) so listen fails; momentarily no free ports under heavy churn.","solutions":["Retry the operation once; ephemeral port bind failures are frequently transient.","Verify the environment allows binding 127.0.0.1 on an ephemeral port (check seccomp/firewall/apparmor profiles, docker network policies).","Raise the file-descriptor limit (ulimit -n) if the process is FD-exhausted.","Reduce simultaneous worktree operations that each start lock workers."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Preflight: can this process bind an ephemeral loopback port right now?\nimport net from \"node:net\";\nfunction canBindLoopback(): Promise<boolean> {\n  return new Promise((resolve) => {\n    const s = net.createServer();\n    s.once(\"error\", () => resolve(false));\n    s.listen(0, \"127.0.0.1\", () => s.close(() => resolve(true)));\n  });\n}","typeGuard":null,"tryCatchPattern":"try {\n  return withWorktreePortRegistryLockSync(home, run);\n} catch (error) {\n  if (error instanceof Error && error.message.includes(\"lock probe\")) {\n    return withWorktreePortRegistryLockSync(home, run); // transient bind failure: retry once\n  }\n  throw error;\n}","preventionTips":["Ensure the runtime allows loopback TCP binds (check seccomp/apparmor/docker policies).","Raise ulimit -n if FD exhaustion is plausible.","Retry once before escalating; ephemeral bind races are short-lived."],"tags":["worktree","port-registry","file-lock","tcp","port-binding"],"backgroundTag":"port-bind-failure","analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-21T17:58:32.592Z","contentChangedAt":"2026-08-21T17:58:32.592Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}