JuliusBrussee/caveman · error
conflicting committed and pending integration journals for $
Error message
conflicting committed and pending integration journals for ${agent}; refusing recovery What it means
Interrupted native installs are recovered using a pending journal plus a committed journal per agent. Recovery expects either a pending journal alone (interrupted install) or a committed journal alone; finding BOTH with different contents is a state the recovery logic cannot interpret safely, so it refuses rather than guess. Identical journals are benign (the pending copy is deleted and recovery is skipped).
Source
Thrown at packages/cli/src/index.ts:6899
return value?.schema_version === 1 && value.agent === agent && Array.isArray(value.operations) ? value : undefined;
} catch { return undefined; }
}
function readNativeJournal(agent: string): NativeJournal | undefined {
return readNativeJournalAt(nativeJournalPath(agent), agent);
}
function readPendingNativeJournal(agent: string): NativeJournal | undefined {
return readNativeJournalAt(nativePendingJournalPath(agent), agent);
}
function recoverPendingNativeInstallUnlocked(agent: NativeAgent): boolean {
const pending = readPendingNativeJournal(agent);
if (!pending) return false;
const committed = readNativeJournal(agent);
if (committed) {
if (JSON.stringify(committed) !== JSON.stringify(pending)) {
throw new Error(`conflicting committed and pending integration journals for ${agent}; refusing recovery`);
}
unlinkSync(nativePendingJournalPath(agent));
return false;
}
const current = pending.operations.map((operation) => ({ file: operation.file, bytes: fileBytes(operation.file) }));
const restored = pending.operations.map((operation) => {
const before = nativeBackupBytes(operation);
const now = fileBytes(operation.file);
const isInstalled = Boolean(now && bytesHash(now) === operation.after_sha256);
const isBefore = operation.before_exists
? Boolean(now && operation.before_sha256 && bytesHash(now) === operation.before_sha256)
: now === null;
if (!isInstalled && !isBefore) {
throw new Error(`${operation.file} changed during interrupted ${agent} install; refusing recovery`);
}
return { file: operation.file, bytes: before };
});
try {View on GitHub (pinned to 27d5a3981a)
Solutions
- Inspect both journal files for the agent and determine which reflects reality on disk.
- If the committed journal is authoritative, delete the pending journal file.
- If the pending journal is authoritative (install never completed), remove the committed journal and re-run recovery.
- If unsure, uninstall and reinstall the agent integration to rebuild consistent state.
Example fix
# before: conflicting journals ls ~/.caveman/*/native/*/journal* # both committed and pending present # after: keep the committed journal, drop the pending copy rm ~/.caveman/.../claude.pending.json && caveman install claude
Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync, existsSync } from "node:fs";
function journalsConsistent(pending: string, committed: string): boolean {
if (!existsSync(pending) || !existsSync(committed)) return true;
try {
return readFileSync(pending, "utf8") === readFileSync(committed, "utf8");
} catch {
return false;
}
} Try / catch
try {
runRecovery(agent);
} catch (e) {
if (e instanceof Error && e.message.includes("conflicting committed and pending")) {
// stop automation; surface state paths to the operator for manual reconciliation
throw new FatalStateError(agent);
}
throw e;
} Prevention
- Never edit caveman state directories by hand while journals exist.
- Avoid killing the CLI mid-install; let it complete or use its own abort path.
- After crashes, run recovery immediately before making other changes to agent files.
When it happens
Trigger: Calling the install/recovery path when both nativePendingJournalPath(agent) and the committed journal exist and JSON.stringify comparison of the two journals differs — typically after a crash between committing and pending-journal cleanup, or after manual edits to the state directory.
Common situations: Process killed at exactly the wrong moment during a native install, users hand-editing or restoring partial copies of the caveman state directory, or downgrades/ upgrades that changed the journal schema between writes.
Related errors
- cannot read pending ${agent} agent-native bundle journal: ${
- cannot read pending ${agent} agent-native removal journal: $
- ${operation.file} changed during interrupted ${agent} instal
- cave_harness_request_invalid
- cave_eve_terminal_${result.status}
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/5b9d943df5e1ece9.
Report an issue: GitHub.