{"record":{"id":"c8d5a3bd7fa57a1a","repo":"paperclipai/paperclip","slug":"worktree-seed-lock-lockpath-belongs-to-exited-p","errorCode":null,"errorMessage":"Worktree seed lock ${lockPath} belongs to exited process ${currentOwner.pid}. Verify that no seed is running, then remove the stale lock and retry.","messagePattern":"Worktree seed lock (.+?) belongs to exited process (.+?)\\. Verify that no seed is running, then remove the stale lock and retry\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/worktree.ts","lineNumber":1534,"sourceCode":"        const current = await fsPromises.readFile(lockPath, \"utf8\").catch(() => null);\n        if (current && parseWorktreeSeedLockOwner(current)?.token === owner.token) {\n          await fsPromises.rm(lockPath, { force: true });\n        }\n      };\n    } catch (error) {\n      if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n    }\n\n    const [rawOwner, lockStat] = await Promise.all([\n      fsPromises.readFile(lockPath, \"utf8\").catch(() => null),\n      fsPromises.stat(lockPath).catch(() => null),\n    ]);\n    const currentOwner = rawOwner ? parseWorktreeSeedLockOwner(rawOwner) : null;\n    const malformedLockIsStale = Boolean(\n      lockStat && Date.now() - lockStat.mtimeMs >= WORKTREE_SEED_LOCK_MALFORMED_STALE_MS,\n    );\n    if (currentOwner && !processIsAlive(currentOwner.pid)) {\n      throw new Error(\n        `Worktree seed lock ${lockPath} belongs to exited process ${currentOwner.pid}. `\n        + \"Verify that no seed is running, then remove the stale lock and retry.\",\n      );\n    }\n    if (!currentOwner && malformedLockIsStale) {\n      throw new Error(\n        `Worktree seed lock ${lockPath} is stale or malformed. `\n        + \"Verify that no seed is running, then remove the stale lock and retry.\",\n      );\n    }\n    await new Promise((resolve) => setTimeout(resolve, WORKTREE_SEED_LOCK_POLL_MS));\n  }\n}\n\nexport async function ensureWorktreeSeeded(\n  opts: WorktreeEnsureSeededOptions = {},\n  dependencies: { seedDatabase?: SeedWorktreeDatabase } = {},\n): Promise<EnsureWorktreeSeededResult> {","sourceCodeStart":1516,"sourceCodeEnd":1552,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/worktree.ts#L1516-L1552","documentation":"Thrown by acquireWorktreeSeedLock when the lock file exists, parses to a valid owner, but the owning process pid is no longer alive (and not EPERM). This means a previous seed process died holding the lock; the guard refuses to silently steal it and asks the user to confirm no seed is running before removing it.","triggerScenarios":"A prior `paperclipai worktree reseed`/seed process was killed (SIGKILL, OOM, terminal closed) mid-seed; the lock file remained; a new seed attempt detects the dead owner.","commonSituations":"Long seed killed by timeout/OOM; user Ctrl-C'd then immediately retried before the lock was released; process died on a different host sharing the filesystem; IDE/shell closed abruptly.","solutions":["Confirm no seed process is running (ps aux | grep paperclip).","Remove the stale lock file at the path shown in the message.","Retry the seed command.","Investigate why the prior process died (OOM, disk full) to avoid recurrence."],"exampleFix":"# before: stale lock from dead pid\n# after\nps aux | grep paperclip   # confirm none running\nrm <lockPath-from-error>\npaperclipai worktree reseed ...","handlingStrategy":"validation","validationCode":"function lockOwnerIsAlive(lockPath: string): boolean {\n  const raw = fs.readFileSync(lockPath, 'utf8');\n  const owner = parseWorktreeSeedLockOwner(raw);\n  return owner ? processIsAlive(owner.pid) : false;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await acquireWorktreeSeedLock(lockPath);\n} catch (e) {\n  if (/belongs to exited process/.test((e as Error).message)) {\n    if (!anySeedRunning()) fs.rmSync(lockPath, { force: true });\n    // retry\n  } else throw e;\n}","preventionTips":["Always let seed processes exit cleanly.","Check ps before removing stale locks.","Wrap seeds in a process supervisor that releases locks."],"tags":["worktree","seed","lock","concurrency","stale"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}