paperclipai/paperclip · error · Error

Cannot determine worktree port reservation lock owner identi

Error message

Cannot determine worktree port reservation lock owner identity

What it means

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.

Source

Thrown at packages/shared/src/worktree-port-registry.ts:308

function stopRegistryLockHeartbeat(lease: RegistryLockLease): void {
  Atomics.store(lease.control, 1, 1);
  Atomics.notify(lease.control, 1);
  lease.worker.postMessage("stop");
  if (Atomics.load(lease.control, 0) === 1) {
    Atomics.wait(lease.control, 0, 1, 2_000);
  }
  void lease.worker.terminate();
}

function acquireRegistryLock(lockPath: string, deadline: number): RegistryLockLease | null {
  try {
    fs.mkdirSync(lockPath);
    const token = `${process.pid}-${randomUUID()}`;
    let lease: RegistryLockLease | null = null;
    try {
      const processIdentity = readProcessIdentity(process.pid);
      if (!processIdentity) {
        throw new Error("Cannot determine worktree port reservation lock owner identity");
      }
      const owner: RegistryLockOwner = {
        version: 1,
        pid: process.pid,
        processIdentity,
        probePort: 1,
        token,
      };
      writeRegistryLockOwner(lockPath, owner);
      lease = startRegistryLockHeartbeat(lockPath, token);
      writeRegistryLockOwner(lockPath, { ...owner, probePort: lease.probePort });
      return lease;
    } catch (error) {
      if (lease) stopRegistryLockHeartbeat(lease);
      fs.rmSync(lockPath, { recursive: true, force: true });
      throw error;
    }
  } catch (error) {

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. 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).
  2. On macOS/other Unix, install/keep procps so `ps -o lstart= -p <pid>` works and PATH contains it.
  3. On Windows, allow powershell.exe -NoProfile -NonInteractive -Command for the service account.
  4. 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.
Defensive patterns

Strategy: validation

Validate before calling

import fs from "node:fs";
function processIdentityReadable(): boolean {
  if (process.platform === "linux") {
    try {
      fs.readFileSync(`/proc/${process.pid}/stat`, "utf8");
      return fs.readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim().length > 0;
    } catch {
      return false;
    }
  }
  return true; // validate `ps` / powershell availability per platform as needed
}

Try / catch

try {
  withWorktreePortRegistryLockSync(home, run);
} catch (error) {
  if (error instanceof Error && error.message.includes("owner identity")) {
    throw new Error("environment cannot provide process identity (/proc or ps); run registry ops on a normal host");
  }
  throw error;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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