JuliusBrussee/caveman · error
existing Aider Caveman block is unjournaled; run `caveman do
Error message
existing Aider Caveman block is unjournaled; run `caveman doctor aider`
What it means
aiderNativeConfig() edits ~/.aider.conf.yml and stamps managed blocks delimited by AIDER_NATIVE_ROUTE/READ BEGIN/END markers. If any marker is present in the file but the install is not journaled (no matching mutation record), the block predates or bypassed Caveman's journal, so safe idempotent merging is impossible and it throws.
Source
Thrown at packages/cli/src/index.ts:6381
file: pluginPath,
before: pluginBefore,
after: Buffer.from(opencodeNativePluginSource()),
kind: "opencode-plugin",
},
];
}
function aiderCorePath(): string {
return join(cavemanHome(), "packs", "aider", "CAVEMAN.md");
}
function aiderCoreSource(): string {
return `${AIDER_NATIVE_CORE_MARKER}\n${NATIVE_CORE}\n\nHost limits: Aider repository map remains authoritative. Caveman observes provider traffic through local proxy; no pre-tool governance or lifecycle interception is active.\n`;
}
function aiderNativeConfig(source: string, route: string, corePath: string): { text: string; routeBlock: string; previousRouteLine: string | null; readBlock: string } {
if ([AIDER_NATIVE_ROUTE_BEGIN, AIDER_NATIVE_ROUTE_END, AIDER_NATIVE_READ_BEGIN, AIDER_NATIVE_READ_END].some((marker) => source.includes(marker))) {
throw new Error("existing Aider Caveman block is unjournaled; run `caveman doctor aider`");
}
const newline = source.includes("\r\n") ? "\r\n" : "\n";
const lines = source.replace(/\r\n/g, "\n").split("\n");
const routeIndexes = lines.flatMap((line, index) => /^openai-api-base\s*:/.test(line) ? [index] : []);
if (routeIndexes.length > 1) throw new Error("Aider config has duplicate openai-api-base keys; refusing unsafe merge");
const routeBlockLines = [AIDER_NATIVE_ROUTE_BEGIN, `openai-api-base: ${yamlQuote(route)}`, AIDER_NATIVE_ROUTE_END];
const routeBlock = routeBlockLines.join(newline);
const previousRouteLine = routeIndexes.length === 1 ? lines[routeIndexes[0]!]! : null;
if (routeIndexes.length === 1) lines.splice(routeIndexes[0]!, 1, ...routeBlockLines);
else {
if (lines.some((line) => line.trim() !== "") && lines[lines.length - 1]?.trim()) lines.push("");
lines.push(...routeBlockLines);
}
const readIndexes = lines.flatMap((line, index) => /^read\s*:/.test(line) ? [index] : []);
if (readIndexes.length > 1) throw new Error("Aider config has duplicate read keys; refusing unsafe merge");
let readBlockLines: string[];
if (readIndexes.length === 1) {View on GitHub (pinned to 27d5a3981a)
Solutions
- Run `caveman doctor aider` to reconcile or remove the unjournaled block
- Manually delete the marker-delimited lines (BEGIN..END inclusive) from ~/.aider.conf.yml, then retry the install
- Avoid restoring config fragments containing Caveman markers without also restoring ~/.caveman state
Example fix
# before — ~/.aider.conf.yml contains stray markers # <<< CAVEMAN NATIVE ROUTE BEGIN <<< openai-api-base: "http://127.0.0.1:8080/w/aider/openai/v1" # <<< CAVEMAN NATIVE ROUTE END <<< # after — those lines removed (or `caveman doctor aider`), then reinstall stamps a journaled block
Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from "node:fs";
const AIDER_MARKERS = [AIDER_NATIVE_ROUTE_BEGIN, AIDER_NATIVE_ROUTE_END, AIDER_NATIVE_READ_BEGIN, AIDER_NATIVE_READ_END];
function aiderConfigClean(path: string): boolean {
try { const src = readFileSync(path, "utf8"); return !AIDER_MARKERS.some((m) => src.includes(m)); }
catch { return true; }
} Try / catch
try { nativeInstallAider(); } catch (e) {
if (e instanceof Error && /unjournaled/.test(e.message)) {
spawnSync("caveman", ["doctor", "aider"], { stdio: "inherit" });
nativeInstallAider();
} else throw e;
} Prevention
- Restore ~/.caveman state together with .aider.conf.yml when recovering from backups
- Never paste Caveman marker blocks between machines
- After any manual edit to managed sections, run caveman doctor aider
When it happens
Trigger: Enabling native Aider routing when ~/.aider.conf.yml already contains any AIDER_NATIVE_ROUTE_BEGIN/END or AIDER_NATIVE_READ_BEGIN/END marker without a corresponding journal entry (e.g. after the journal was cleared, or markers were pasted by hand).
Common situations: Restoring .aider.conf.yml from a backup that included Caveman markers while ~/.caveman state/journal was reset; reinstalling caveman after wiping its home dir; sharing dotfiles between machines.
Related errors
- existing Hermes Caveman native block is unjournaled; run `ca
- cannot read ${agent} agent-native bundle journal: ${(error a
- existing Gemini Caveman routing block is corrupted; run `cav
- Aider config has duplicate openai-api-base keys; refusing un
- Aider config has duplicate read keys; refusing unsafe merge
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/98e4f11cf2327878.
Report an issue: GitHub.