JuliusBrussee/caveman · error
exists and is not exact Caveman-owned content; refusing to…
Error message
${corePath} exists and is not exact Caveman-owned content; refusing to overwrite it What it means
The Aider installer generates the Caveman core source and writes it to aiderCorePath(). If a file already exists at that path and its byte content is not exactly equal to the generated core source, the installer refuses to overwrite it, since it cannot verify the file is Caveman-owned/current.
Solutions
- Delete (or back up and remove) the existing core file and re-run the enable command so Caveman writes a fresh copy.
- Run `caveman doctor aider` to detect and repair the stale core file.
- If you customized the core, save your changes elsewhere, delete the file, re-enable, then reapply customizations understanding they may be overwritten on upgrade.
- If a version upgrade caused the mismatch, reinstall via the current `caveman` version so core text matches.
Example fix
// before: core file edited, mismatch with generated source cat ~/.config/caveman/aider-core.md # hand-edited content // after mv ~/.config/caveman/aider-core.md ~/aider-core.md.bak caveman enable aider # rewrites exact generated core with AIDER_NATIVE_CORE_MARKER
Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync, existsSync } from 'fs';
const corePath = aiderCorePath();
if (existsSync(corePath) && readFileSync(corePath, 'utf8') !== expectedCoreSource()) {
// delete or restore the core file before enabling
} Try / catch
try {
await cavemanEnableAider();
} catch (e) {
if (String(e.message).includes('not exact Caveman-owned content')) {
rename(corePath, corePath + '.bak');
await cavemanEnableAider();
}
} Prevention
- Treat the generated Aider core file as owned by Caveman; do not edit it.
- Store custom prompt changes in separate Aider conventions files.
- Re-run the installer (not manual edits) after Caveman upgrades so the core text stays current.
- Use `caveman doctor aider` to detect core drift.
When it happens
Trigger: Running the Aider enable flow when the core file exists but its contents differ from the currently generated core (edited by hand, truncated, or produced by a different Caveman version with different core text).
Common situations: Users tweaking the core prompt file to customize behavior; a Caveman upgrade changed NATIVE_CORE text so an old core file no longer matches byte-for-byte; partial writes from an interrupted install.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- existing Aider Caveman block is unjournaled; run `caveman…
- existing Codex Caveman block is corrupted; run `caveman…
- existing Hermes Caveman native block is unjournaled; run…
- already exists and is not Caveman-owned; refusing to…
- already exists and is not Caveman-owned; refusing to…
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/f30085bb32b398d0.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:7454
lines.splice(end, 0, ...readBlockLines);
} else {
if (lines.some((line) => line.trim() !== "") && lines[lines.length - 1]?.trim()) lines.push("");
readBlockLines = [AIDER_NATIVE_READ_BEGIN, "read:", ` - ${yamlQuote(corePath)}`, AIDER_NATIVE_READ_END];
lines.push(...readBlockLines);
}
const readBlock = readBlockLines.join(newline);
const text = lines.join(newline).replace(/(?:\r?\n)+$/, "") + newline;
return { text, routeBlock, previousRouteLine, readBlock };
}
function aiderNativeMutations(gw: string): NativeMutation[] {
const configPath = join(homedir(), ".aider.conf.yml");
const configBefore = fileBytes(configPath);
const corePath = aiderCorePath();
const coreBefore = fileBytes(corePath);
const core = aiderCoreSource();
if (coreBefore && coreBefore.toString("utf8") !== core) {
throw new Error(`${corePath} exists and is not exact Caveman-owned content; refusing to overwrite it`);
}
const route = appendUrlPath(gw, "/w/aider/openai/v1");
const native = aiderNativeConfig(configBefore?.toString("utf8") ?? "", route, corePath);
return [
{
file: configPath,
before: configBefore,
after: Buffer.from(native.text),
kind: "aider-config",
owned: { route, route_block: native.routeBlock, previous_route_line: native.previousRouteLine, read_block: native.readBlock, core_path: corePath },
},
{
file: corePath,
before: coreBefore,
after: Buffer.from(core),
kind: "aider-core",
owned: { marker: AIDER_NATIVE_CORE_MARKER },
},View on GitHub (pinned to 3ee70a1026)