paperclipai/paperclip · error

git worktree cleanup lock is already held

Error message

git worktree cleanup lock is already held

What it means

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.

Source

Thrown at server/src/services/workspace-runtime.ts:3636

      const lock = lockHandles[index];
      if (!lock || (kind && lock.kind !== kind)) continue;
      lockHandles.splice(index, 1);
      await lock.handle.close().catch(() => {});
      await fs.rm(lock.lockPath, { force: true }).catch(() => {});
    }
  }

  try {
    for (const lock of locks) {
      lockHandles.push({
        ...lock,
        handle: await fs.open(lock.lockPath, "wx", 0o600),
      });
    }
  } catch (error) {
    await releaseLocks();
    if ((error as NodeJS.ErrnoException).code === "EEXIST") {
      throw new Error("git worktree cleanup lock is already held");
    }
    throw error;
  }

  return {
    // Branch deletion must acquire this native ref lock itself. Callers release
    // only that lock after the guarded worktree removal, while retaining the
    // index and HEAD locks until the whole cleanup transaction finishes.
    releaseBranchRefLock: () => releaseLocks("branch"),
    release: () => releaseLocks(),
  };
}

async function deleteGitBranchAtVerifiedTip(input: {
  repoRoot: string;
  branchName: string;
  expectedHeadSha: string;
  recorder?: WorkspaceOperationRecorder | null;

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Another cleanup holds the worktree lock. Wait for it to finish; if stale, remove the lock after confirming no cleanup is running.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at server/src/services/workspace-runtime.ts:3579 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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