{"record":{"id":"070c175140fe76c7","repo":"paperclipai/paperclip","slug":"git-worktree-cleanup-lock-is-already-held","errorCode":null,"errorMessage":"git worktree cleanup lock is already held","messagePattern":"git worktree cleanup lock is already held","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/workspace-runtime.ts","lineNumber":3636,"sourceCode":"      const lock = lockHandles[index];\n      if (!lock || (kind && lock.kind !== kind)) continue;\n      lockHandles.splice(index, 1);\n      await lock.handle.close().catch(() => {});\n      await fs.rm(lock.lockPath, { force: true }).catch(() => {});\n    }\n  }\n\n  try {\n    for (const lock of locks) {\n      lockHandles.push({\n        ...lock,\n        handle: await fs.open(lock.lockPath, \"wx\", 0o600),\n      });\n    }\n  } catch (error) {\n    await releaseLocks();\n    if ((error as NodeJS.ErrnoException).code === \"EEXIST\") {\n      throw new Error(\"git worktree cleanup lock is already held\");\n    }\n    throw error;\n  }\n\n  return {\n    // Branch deletion must acquire this native ref lock itself. Callers release\n    // only that lock after the guarded worktree removal, while retaining the\n    // index and HEAD locks until the whole cleanup transaction finishes.\n    releaseBranchRefLock: () => releaseLocks(\"branch\"),\n    release: () => releaseLocks(),\n  };\n}\n\nasync function deleteGitBranchAtVerifiedTip(input: {\n  repoRoot: string;\n  branchName: string;\n  expectedHeadSha: string;\n  recorder?: WorkspaceOperationRecorder | null;","sourceCodeStart":3618,"sourceCodeEnd":3654,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/services/workspace-runtime.ts#L3618-L3654","documentation":"Worktree cleanup tried to exclusively create (open 'wx') its lock files but hit EEXIST, meaning another cleanup process already holds the git worktree cleanup lock. The lock serializes concurrent cleanups of the same worktrees.","triggerScenarios":"Thrown at server/src/services/workspace-runtime.ts:3579 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Another cleanup holds the worktree lock. Wait for it to finish; if stale, remove the lock after confirming no cleanup is running."],"exampleFix":null,"handlingStrategy":"retry","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-14T00:17:10.932Z"}