{"record":{"id":"5533bfd120cc3315","repo":"JuliusBrussee/caveman","slug":"agent-servername-mcp-config-or-ownership-jou","errorCode":null,"errorMessage":"${agent} ${serverName} MCP config or ownership journal changed during interrupted transaction; refusing destructive recovery","messagePattern":"(.+?) (.+?) MCP config or ownership journal changed during interrupted transaction; refusing destructive recovery","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":12476,"sourceCode":"  const markerIsBefore = markerHash === journal.marker_before_sha256;\n  const markerIsAfter = markerHash === journal.marker_after_sha256;\n  const removePendingCopies = () => {\n    if (configPending) durableUnlink(configPendingPath);\n    if (locatorPending) durableUnlink(locatorPath);\n  };\n\n  if (configIsAfter && markerIsAfter) {\n    removePendingCopies();\n    process.stderr.write(`${mark(\"warn\")} finalized interrupted ${agent} ${serverName} MCP transaction\\n`);\n    return \"finalized\";\n  }\n  if (configIsBefore && markerIsBefore) {\n    removePendingCopies();\n    process.stderr.write(`${mark(\"warn\")} discarded uncommitted ${agent} ${serverName} MCP transaction\\n`);\n    return \"discarded\";\n  }\n  if ((!configIsBefore && !configIsAfter) || (!markerIsBefore && !markerIsAfter)) {\n    throw new Error(`${agent} ${serverName} MCP config or ownership journal changed during interrupted transaction; refusing destructive recovery`);\n  }\n  if (!configPending || !locatorPending) {\n    throw new Error(`${agent} ${serverName} MCP transaction lost one durable journal copy; refusing destructive recovery`);\n  }\n\n  if (!configIsBefore) {\n    durableReplaceFileIfUnchanged(configPath, configCurrent, configBefore, journal.config_before_mode);\n  }\n  if (!markerIsBefore) {\n    durableReplaceFileIfUnchanged(markerPath, markerCurrent, markerBefore, journal.marker_before_mode);\n  }\n  if (optionalBytesHash(fileBytes(configPath)) !== journal.config_before_sha256\n    || optionalBytesHash(fileBytes(markerPath)) !== journal.marker_before_sha256) {\n    throw new Error(`${agent} ${serverName} MCP rollback postflight mismatch`);\n  }\n  removePendingCopies();\n  process.stderr.write(`${mark(\"warn\")} rolled back interrupted ${agent} ${serverName} MCP transaction\\n`);\n  return \"rolled-back\";","sourceCodeStart":12458,"sourceCodeEnd":12494,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L12458-L12494","documentation":"Recovery guard after an interrupted MCP ownership transaction: neither the before- nor after-hash of the config (or of the ownership journal) matches the journal's recorded hashes, yet pending copies exist. The on-disk state was altered by something other than the interrupted transaction, so automatic rollback/finalization would destroy data and is refused.","triggerScenarios":"Thrown at packages/cli/src/index.ts:12476 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the config file and ownership journal manually and reconcile them with the pending copies before re-running","Remove stale pending journal copies and the registration/marker pair by hand to restore a consistent state, then retry the install","Ensure no other process edits the MCP config or journal while a transaction is in flight"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-09-06T12:00:26.372Z","contentChangedAt":"2026-09-06T12:00:26.372Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}