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_sha256View on GitHub (pinned to 5184b3d11a)
Solutions
- Re-run the command so the existing interrupted transaction is recovered or rolled back first
- If recovery is impossible, manually delete the stale journal under cavemanHome()/mcp after reconciling the config and marker, then retry
- 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.