JuliusBrussee/caveman · error · Error

${agent} ${serverName} MCP transaction journal already exist

Error message

${agent} ${serverName} MCP transaction journal already exists; refusing overwrite

What it means

Transaction-invariant guard when creating the durable journal for an MCP install/uninstall: a journal file for this agent/server/action already exists on disk. A leftover journal means a previous transaction is unfinished or crashed, and overwriting it would orphan that recovery state, so the new transaction refuses to start.

Source

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

    server_name: serverName,
    action,
    config_path: plan.path,
    marker_path: markerPath,
    config_before_base64: plan.before?.toString("base64") ?? null,
    config_before_mode: plan.beforeMode,
    config_before_sha256: optionalBytesHash(plan.before),
    config_after_sha256: optionalBytesHash(plan.after),
    marker_before_base64: markerBefore?.toString("base64") ?? null,
    marker_before_mode: markerBeforeMode,
    marker_before_sha256: optionalBytesHash(markerBefore),
    marker_after_base64: markerAfter?.toString("base64") ?? null,
    marker_after_sha256: optionalBytesHash(markerAfter),
  };
  const locatorPath = `${markerPath}.pending`;
  const configPendingPath = mcpConfigPendingJournalPath(plan.path);
  const pendingBytes = Buffer.from(JSON.stringify(journal, null, 2) + "\n");
  if (fileBytes(locatorPath) !== null || fileBytes(configPendingPath) !== null) {
    throw new Error(`${agent} ${serverName} MCP transaction journal already exists; refusing overwrite`);
  }
  durableCreateFile(locatorPath, pendingBytes);
  try {
    durableCreateFile(configPendingPath, pendingBytes);
  } catch (error) {
    durableUnlink(locatorPath);
    throw error;
  }

  try {
    if (action === "install") {
      if (plan.changed) durableReplaceFileIfUnchanged(plan.path, plan.before, plan.after, plan.beforeMode);
      if (!optionalBytesEqual(markerBefore, markerAfter)) durableReplaceFileIfUnchanged(markerPath, markerBefore, markerAfter);
    } else {
      if (!optionalBytesEqual(markerBefore, markerAfter)) durableReplaceFileIfUnchanged(markerPath, markerBefore, markerAfter);
      if (plan.changed) durableReplaceFileIfUnchanged(plan.path, plan.before, plan.after, plan.beforeMode);
    }
    if (optionalBytesHash(fileBytes(plan.path)) !== journal.config_after_sha256

View on GitHub (pinned to 5184b3d11a)

Solutions

  1. Re-run the command so the existing interrupted transaction is recovered or rolled back first
  2. If recovery is impossible, manually delete the stale journal under cavemanHome()/mcp after reconciling the config and marker, then retry
  3. Ensure only one Caveman MCP transaction per agent/server runs at a time
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/cli/src/index.ts:12546 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/fe285da33eda9809. Report an issue: GitHub.