{"record":{"id":"5a8c106be181c4a0","repo":"paperclipai/paperclip","slug":"refusing-terminal-workspace-cleanup-because-the-gi-5a8c10","errorCode":null,"errorMessage":"Refusing terminal workspace cleanup because the git worktree changed after delivery was verified","messagePattern":"Refusing terminal workspace cleanup because the git worktree changed after delivery was verified","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/execution-workspaces.ts","lineNumber":1470,"sourceCode":"        sourceIssueTerminal,\n        mergedPullRequest,\n        pullRequestStateUnknown,\n        isMergedIntoBase: git?.isMergedIntoBase ?? null,\n      }),\n      sourceIssueTerminal,\n      subtreeTerminal,\n      cooldownAnchor,\n      workspaceDirty: Boolean(git?.hasDirtyTrackedFiles || git?.hasUntrackedFiles),\n      workspaceHeadSha,\n    };\n  }\n\n  async function assertTerminalCleanupGitStateUnchanged(\n    workspace: ExecutionWorkspaceRow,\n    expectedHeadSha: string | null,\n  ) {\n    if (workspace.providerType !== \"git_worktree\") return;\n    const workspacePath = readNullableString(workspace.providerRef) ?? readNullableString(workspace.cwd);\n    if (!workspacePath || !expectedHeadSha) {\n      throw new Error(\"Refusing terminal workspace cleanup because the expected git HEAD is unknown\");\n    }\n\n    const [current, currentHeadSha, currentBranchName] = await Promise.all([\n      inspectGitCloseReadiness(toExecutionWorkspace(workspace)),\n      readGitStdout([\"rev-parse\", \"HEAD\"], workspacePath).catch(() => null),\n      readGitStdout([\"symbolic-ref\", \"--quiet\", \"--short\", \"HEAD\"], workspacePath).catch(() => null),\n    ]);\n    if (!current.statusInspectionSucceeded) {\n      throw new Error(\"Refusing terminal workspace cleanup because the git status could not be verified\");\n    }\n    if (\n      !current.git?.repoRoot\n      || current.git.hasDirtyTrackedFiles\n      || current.git.hasUntrackedFiles\n      || currentHeadSha !== expectedHeadSha\n      || (workspace.branchName && currentBranchName !== workspace.branchName)","sourceCodeStart":1452,"sourceCodeEnd":1488,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/execution-workspaces.ts#L1452-L1488","documentation":"Integrity-violation check in assertTerminalCleanupGitStateUnchanged: the git inspection succeeded, but the worktree's current HEAD/branch differs from the expectedHeadSha captured when delivery was verified — the workspace changed after its final state was signed off. Terminal cleanup is refused to avoid destroying unaccounted-for work.","triggerScenarios":"Thrown at server/src/services/execution-workspaces.ts:1464 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the worktree changes made after delivery verification; restore the verified state or clean up manually."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}