JuliusBrussee/caveman · error · Error
MCP transaction failed and rolled back
Error message
${agent} ${serverName} MCP transaction failed and rolled back: ${(error as Error).message} What it means
Thrown when a kilo/qwen MCP config transaction fails but the ownership journal successfully rolled the change back ('failed and rolled back'). The original error is preserved in the message; the native config should be in its pre-transaction state.
Solutions
- Read the original error embedded in the message and fix that root cause
- Verify the agent's native config was rolled back and re-run the install command
- Ensure the agent process is not holding the config file open/locked during install
- Check disk space and file permissions on the config directory
Defensive patterns
Strategy: try-catch
Validate before calling
assertWritable(mcpConfigDir(agent));
Try / catch
try { installMcp(agent, serverName) } catch (e) {
// message ends with 'rolled back'; log original cause and retry after fixing
console.error(String(e));
} Prevention
- Close the target agent before changing its MCP config
- Back up the native config before install
- Keep CLI and agent versions compatible
When it happens
Trigger: Any failure inside the kilo/qwen MCP install/remove transaction body (write error, spawn failure, validation failure) where recoverOwnedMcpTransaction succeeded in finalizing/rolling back.
Common situations: Agent binary rejected the config change; native config file read-only; schema change in the agent's config format broke a mid-transaction step.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- MCP transaction failed and safe recovery was blocked: …
- MCP changes require the ownership transaction
- : MCP ownership journal failed; native config may already…
- MCP rollback postflight mismatch
- MCP transaction postflight mismatch
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/a6beedd070e0274a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:12949
} 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
|| optionalBytesHash(fileBytes(markerPath)) !== journal.marker_after_sha256) {
throw new Error(`${agent} ${serverName} MCP transaction postflight mismatch`);
}
durableUnlink(configPendingPath);
durableUnlink(locatorPath);
return true;
} catch (error) {
try {
const recovery = recoverOwnedMcpTransaction(readOwnedMcpConfigPending(plan.path) ?? readOwnedMcpPendingLocator(agent, serverName));
if (recovery === "finalized") return true;
} catch (recoveryError) {
throw new Error(`${agent} ${serverName} MCP transaction failed and safe recovery was blocked: ${(recoveryError as Error).message}; original error: ${(error as Error).message}`);
}
throw new Error(`${agent} ${serverName} MCP transaction failed and rolled back: ${(error as Error).message}`);
}
}
function withOwnedMcpTransactionLock<T>(
agent: "kilo" | "qwen",
serverName: string,
run: (lockedConfigPath: string) => T,
): T {
const markerPath = canonicalOwnedMcpMarkerPath(agent, serverName);
return withMcpConfigLock(markerPath, () => {
const activeConfigPath = () => canonicalMcpConfigPath(agent === "kilo" ? kiloConfigPath() : qwenConfigPath());
const resourcePath = () => readOwnedMcpPendingLocator(agent, serverName)?.journal.config_path
?? readMcpServerMarker(agent, serverName)?.config_path
?? activeConfigPath();
for (let attempt = 0; attempt < 8; attempt++) {
const lockPath = canonicalMcpConfigPath(resourcePath());
const outcome = withMcpConfigLock<{ retry: true } | { retry: false; value: T }>(lockPath, () => {
const locatorPending = readOwnedMcpPendingLocator(agent, serverName);View on GitHub (pinned to 3ee70a1026)