JuliusBrussee/caveman · error · Error

${agent} ${serverName} MCP config or ownership journal chang

Error message

${agent} ${serverName} MCP config or ownership journal changed during interrupted transaction; refusing destructive recovery

What it means

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.

Source

Thrown at packages/cli/src/index.ts:12476

  const markerIsBefore = markerHash === journal.marker_before_sha256;
  const markerIsAfter = markerHash === journal.marker_after_sha256;
  const removePendingCopies = () => {
    if (configPending) durableUnlink(configPendingPath);
    if (locatorPending) durableUnlink(locatorPath);
  };

  if (configIsAfter && markerIsAfter) {
    removePendingCopies();
    process.stderr.write(`${mark("warn")} finalized interrupted ${agent} ${serverName} MCP transaction\n`);
    return "finalized";
  }
  if (configIsBefore && markerIsBefore) {
    removePendingCopies();
    process.stderr.write(`${mark("warn")} discarded uncommitted ${agent} ${serverName} MCP transaction\n`);
    return "discarded";
  }
  if ((!configIsBefore && !configIsAfter) || (!markerIsBefore && !markerIsAfter)) {
    throw new Error(`${agent} ${serverName} MCP config or ownership journal changed during interrupted transaction; refusing destructive recovery`);
  }
  if (!configPending || !locatorPending) {
    throw new Error(`${agent} ${serverName} MCP transaction lost one durable journal copy; refusing destructive recovery`);
  }

  if (!configIsBefore) {
    durableReplaceFileIfUnchanged(configPath, configCurrent, configBefore, journal.config_before_mode);
  }
  if (!markerIsBefore) {
    durableReplaceFileIfUnchanged(markerPath, markerCurrent, markerBefore, journal.marker_before_mode);
  }
  if (optionalBytesHash(fileBytes(configPath)) !== journal.config_before_sha256
    || optionalBytesHash(fileBytes(markerPath)) !== journal.marker_before_sha256) {
    throw new Error(`${agent} ${serverName} MCP rollback postflight mismatch`);
  }
  removePendingCopies();
  process.stderr.write(`${mark("warn")} rolled back interrupted ${agent} ${serverName} MCP transaction\n`);
  return "rolled-back";

View on GitHub (pinned to 5184b3d11a)

Solutions

  1. Inspect the config file and ownership journal manually and reconcile them with the pending copies before re-running
  2. Remove stale pending journal copies and the registration/marker pair by hand to restore a consistent state, then retry the install
  3. Ensure no other process edits the MCP config or journal while a transaction is in flight
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/cli/src/index.ts:12476 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-09-06). Data as JSON: /api/errors/5533bfd120cc3315. Report an issue: GitHub.