paperclipai/paperclip · error

Refusing terminal workspace cleanup because the expected git

Error message

Refusing terminal workspace cleanup because the expected git HEAD is unknown

What it means

Fail-closed safety check in assertTerminalCleanupGitStateUnchanged: a git_worktree workspace is about to be terminally cleaned up, but either its local path or the expected HEAD SHA (workspaceHeadSha captured when delivery was verified) is unknown. Without a pinned expected HEAD the 'unchanged since verification' invariant cannot be checked, so destructive cleanup is refused.

Source

Thrown at server/src/services/execution-workspaces.ts:1446

        pullRequestStateUnknown,
        isMergedIntoBase: git?.isMergedIntoBase ?? null,
      }),
      sourceIssueTerminal,
      subtreeTerminal,
      cooldownAnchor,
      workspaceDirty: Boolean(git?.hasDirtyTrackedFiles || git?.hasUntrackedFiles),
      workspaceHeadSha,
    };
  }

  async function assertTerminalCleanupGitStateUnchanged(
    workspace: ExecutionWorkspaceRow,
    expectedHeadSha: string | null,
  ) {
    if (workspace.providerType !== "git_worktree") return;
    const workspacePath = readNullableString(workspace.providerRef) ?? readNullableString(workspace.cwd);
    if (!workspacePath || !expectedHeadSha) {
      throw new Error("Refusing terminal workspace cleanup because the expected git HEAD is unknown");
    }

    const [current, currentHeadSha, currentBranchName] = await Promise.all([
      inspectGitCloseReadiness(toExecutionWorkspace(workspace)),
      readGitStdout(["rev-parse", "HEAD"], workspacePath).catch(() => null),
      readGitStdout(["symbolic-ref", "--quiet", "--short", "HEAD"], workspacePath).catch(() => null),
    ]);
    if (!current.statusInspectionSucceeded) {
      throw new Error("Refusing terminal workspace cleanup because the git status could not be verified");
    }
    if (
      !current.git?.repoRoot
      || current.git.hasDirtyTrackedFiles
      || current.git.hasUntrackedFiles
      || currentHeadSha !== expectedHeadSha
      || (workspace.branchName && currentBranchName !== workspace.branchName)
    ) {
      throw new Error("Refusing terminal workspace cleanup because the git worktree changed after delivery was verified");

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. Restore the expected git HEAD record for the workspace before cleanup, or clean up the workspace manually.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/execution-workspaces.ts:1446 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/c2186368230f6619. Report an issue: GitHub.