JuliusBrussee/caveman · error · Error
${target} integration journal disappeared during repair
Error message
${target} integration journal disappeared during repair What it means
repairNativeAgent first checks that either the committed journal or a pending journal exists, then inside the integration lock runs crash recovery (recoverPendingNativeInstallUnlocked) and re-reads the committed journal; this error means the re-read found nothing. The usual cause is that a pending (crashed) transaction was rolled back by recovery — leaving no committed journal — or a concurrent `caveman disable <agent>` deleted the journal between the two reads.
Source
Thrown at packages/cli/src/index.ts:8294
return false;
}
cleanupNativeAgentFiles(target, disabled);
const name = findAgent(target)?.display_name ?? target;
process.stderr.write(`${mark("ok")} ${name}: ${target === "aider" ? "shallow" : "native"} Caveman disabled; unrelated host edits preserved\n`);
return true;
}
function repairNativeAgent(target: NativeAgent): void {
if (!readNativeJournal(target) && !readPendingNativeJournal(target)) {
enableNative([target]);
return;
}
const profile = findAgent(target)!;
const gw = gatewayURL();
withIntegrationLock(target, () => {
recoverPendingNativeInstallUnlocked(target);
const journal = readNativeJournal(target);
if (!journal) throw new Error(`${target} integration journal disappeared during repair`);
if (!which(binOf(profile))) throw new Error(`${profile.display_name} not found on PATH`);
const mcpBinary = target === "aider" ? undefined : nativeMcpBinaryRequired();
nativeProxyBinaryRequired(gw);
const journalBytes = readFileSync(nativeJournalPath(target));
const current = restoreNativeJournalFiles(journal);
try {
const mutations = nativeMutationsFor(target, gw, mcpBinary);
applyNativeMutations(target, profile, mutations);
} catch (error) {
for (const item of current) {
try { writeNativeRestoration(item.file, item.bytes); } catch { /* original error remains authority */ }
}
atomicWriteFile(nativeJournalPath(target), journalBytes);
throw error;
}
});
process.stderr.write(`${mark("ok")} ${profile.display_name}: native Caveman repaired; unrelated host edits preserved\n`);
}View on GitHub (pinned to 5184b3d11a)
Solutions
- Simply rerun `caveman doctor <agent> --fix` — with both journals now absent, it takes the enableNative path and rebuilds the integration cleanly
- Make sure no other caveman disable/enable/doctor command for the same agent is running concurrently; run integration commands serially
- If it recurs without concurrency, check for external deletion of ~/.caveman/integrations/<agent>.json (cron, dotfile cleaners)
Example fix
# before: recovery rolled back a pending enable, journal gone caveman doctor claude --fix # >> claude integration journal disappeared during repair # after: state is now consistent; rerun rebuilds the integration caveman doctor claude --fix
Defensive patterns
Strategy: retry
Validate before calling
// Ensure no concurrent integration command and journals are stable before repair
import { existsSync } from 'node:fs';
const home = process.env.CAVEMAN_HOME ?? `${process.env.HOME}/.caveman`;
const committed = `${home}/integrations/codex.json`;
const pending = `${home}/integrations/.pending-codex.json`;
// snapshot twice with a beat between; require stability if you plan to repair
const snap = () => [committed, pending].map((p) => existsSync(p)).join(',');
const a = snap(); await new Promise((r) => setTimeout(r, 250));
if (snap() !== a) console.error('journal state changing — another caveman process is active'); Try / catch
catch (err) {
if (err.message.includes('journal disappeared during repair')) {
// state resolved (pending rolled back or concurrent disable finished):
// re-check and run the command again from scratch — it now takes the enable path
return execSync('caveman doctor codex --fix');
}
throw err;
} Prevention
- Never run caveman disable/enable/doctor for the same agent concurrently
- In scripts, sequence integration commands with `&&` rather than parallel jobs
- Do not delete ~/.caveman/integrations files while a command is running
When it happens
Trigger: `caveman doctor <agent> --fix` when a crashed `caveman enable <agent>` left a .pending-<agent>.json that recovery rolls back (enable never committed), or when another terminal runs `caveman disable <agent>` at the same moment. A journal file deleted by hand mid-command also triggers it.
Common situations: Interrupting an enable (Ctrl-C, machine sleep, crash) and then immediately running doctor --fix; running disable and doctor concurrently from two shells; scripts invoking multiple caveman integration commands in parallel.
Related errors
- conflicting committed and pending integration journals for $
- cave_tool_result_requires_recovery
- cave_tool_result_recovery_mismatch
- native session key chmod dir: %w
- ${file} already exists with non-canonical content; refusing
AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-08-18).
Data as JSON: /api/errors/d6050e5ddd7260fa.
Report an issue: GitHub.