{"record":{"id":"a8140dfcdf7490f3","repo":"paperclipai/paperclip","slug":"cannot-determine-worktree-port-reservation-lock-ow","errorCode":null,"errorMessage":"Cannot determine worktree port reservation lock owner identity","messagePattern":"Cannot determine worktree port reservation lock owner identity","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/src/worktree-port-registry.ts","lineNumber":308,"sourceCode":"function 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()}`;\n    let lease: RegistryLockLease | null = null;\n    try {\n      const processIdentity = readProcessIdentity(process.pid);\n      if (!processIdentity) {\n        throw new Error(\"Cannot determine worktree port reservation lock owner identity\");\n      }\n      const owner: RegistryLockOwner = {\n        version: 1,\n        pid: process.pid,\n        processIdentity,\n        probePort: 1,\n        token,\n      };\n      writeRegistryLockOwner(lockPath, owner);\n      lease = startRegistryLockHeartbeat(lockPath, token);\n      writeRegistryLockOwner(lockPath, { ...owner, probePort: lease.probePort });\n      return lease;\n    } catch (error) {\n      if (lease) stopRegistryLockHeartbeat(lease);\n      fs.rmSync(lockPath, { recursive: true, force: true });\n      throw error;\n    }\n  } catch (error) {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/packages/shared/src/worktree-port-registry.ts#L290-L326","documentation":"Thrown by acquireRegistryLock when readProcessIdentity(process.pid) returns null: the registry could not build a unique owner identity for the current process. On Linux the identity is bootId + process start ticks read from /proc; on Windows it comes from PowerShell; elsewhere from `ps -o lstart=`. Without a trustworthy identity, stale-lock detection could confuse PID reuse, so the lock is refused.","triggerScenarios":"On Linux: /proc/<pid>/stat or /proc/sys/kernel/random/boot_id unreadable (hardened container, hidepid mount, chroot without /proc). On Windows: PowerShell invocation blocked by policy. On macOS/other: the `ps` binary missing from PATH or failing. Any of these makes readProcessIdentity return null during lock acquisition.","commonSituations":"Minimal container images (distroless/busybox without procps, or proc mounted with hidepid=2); gVisor/Firecracker sandboxes with partial /proc; Windows application-control policies (WDAC/AppLocker) blocking powershell.exe; PATH stripped in service contexts so `ps` is not found.","solutions":["On Linux, ensure /proc is mounted and readable for the process's own /proc/<pid>/stat and /proc/sys/kernel/random/boot_id (avoid hidepid=2 restrictions).","On macOS/other Unix, install/keep procps so `ps -o lstart= -p <pid>` works and PATH contains it.","On Windows, allow powershell.exe -NoProfile -NonInteractive -Command for the service account.","If the environment cannot satisfy this, run the worktree/port-registry operations on a host with a normal /proc instead of inside the hardened sandbox."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import fs from \"node:fs\";\nfunction processIdentityReadable(): boolean {\n  if (process.platform === \"linux\") {\n    try {\n      fs.readFileSync(`/proc/${process.pid}/stat`, \"utf8\");\n      return fs.readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\").trim().length > 0;\n    } catch {\n      return false;\n    }\n  }\n  return true; // validate `ps` / powershell availability per platform as needed\n}","typeGuard":null,"tryCatchPattern":"try {\n  withWorktreePortRegistryLockSync(home, run);\n} catch (error) {\n  if (error instanceof Error && error.message.includes(\"owner identity\")) {\n    throw new Error(\"environment cannot provide process identity (/proc or ps); run registry ops on a normal host\");\n  }\n  throw error;\n}","preventionTips":["Do not run worktree/port-registry operations inside hidepid or /proc-less sandboxes.","Keep procps installed and on PATH on Unix; allow powershell.exe on Windows service accounts.","Smoke-test lock acquisition in new base images before fan-out."],"tags":["worktree","port-registry","file-lock","process-identity","proc","linux"],"backgroundTag":"process-identity-unavailable","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"}