JuliusBrussee/caveman · error
${file} already exists with non-canonical content; refusing
Error message
${file} already exists with non-canonical content; refusing to overwrite an unjournaled skill What it means
In preflightAgentNativeBundleComponents with no existing bundle journal, a skill file that already exists on disk but does not byte-equal the canonical embedded body is treated as foreign user content. Since there is no journal to prove Caveman wrote it, overwriting would destroy someone else's work — hence the refusal.
Source
Thrown at packages/cli/src/index.ts:2544
function ensureAgentNativeIntegration(agent: "claude" | "codex"): void {
const status = nativeIntegrationStatus(agent);
if (!status.installed) {
enableNative([agent]);
return;
}
if (status.state !== "installed") repairNativeAgent(agent);
}
function preflightAgentNativeBundleComponents(
agent: "claude" | "codex",
existingBundle: AgentNativeBundleJournal | null,
): void {
const previousSkills = new Map(existingBundle?.skills.map((skill) => [skill.file, skill]) ?? []);
for (const { file, body } of agentNativeSkillFiles(agent)) {
const current = fileBytes(file);
if (!existingBundle) {
if (current && !current.equals(Buffer.from(body))) {
throw new Error(`${file} already exists with non-canonical content; refusing to overwrite an unjournaled skill`);
}
continue;
}
const previous = previousSkills.get(file);
if (current && !current.equals(Buffer.from(body)) && (!previous || bytesHash(current) !== previous.after_sha256)) {
throw new Error(`${file} changed after setup; refusing to overwrite user skill edits`);
}
}
if (agent === "claude") {
const actual = claudeMcpRegistration("caveman-cloud");
const marker = readMcpServerMarker("claude", "caveman-cloud");
if (actual.present && !marker) {
throw new Error("Claude caveman-cloud MCP exists but is not Caveman-journaled; refusing overwrite");
}
if (actual.present && marker && !agentNativeCloudMcpMatches("claude", marker)) {
throw new Error("Claude caveman-cloud MCP changed after setup; refusing to overwrite user fields");
}
return;View on GitHub (pinned to 27d5a3981a)
Solutions
- If the existing file is yours, back it up and move it away (or rename its directory), then re-run setup
- If it is a stale Caveman artifact from an unjournaled older install, verify and delete it so setup can write the canonical body
- If you want to keep a customized version, maintain it under a different skill name so it cannot collide
Defensive patterns
Strategy: validation
Validate before calling
function skillPathIsFreeOrCanonical(file: string, canonicalBody: Buffer): boolean {
try {
const cur = readFileSync(file);
return cur.equals(canonicalBody);
} catch { return true; } // absent = fine
} Type guard
function isUnjournaledSkillError(e: unknown): boolean {
return e instanceof Error && e.message.includes("already exists with non-canonical content");
} Try / catch
try {
runCavemanSetup();
} catch (e) {
if (isUnjournaledSkillError(e)) {
// message names the file — back it up, move it away, re-run
} else throw e;
} Prevention
- Avoid naming your own skills identically to caveman's agent-native suite
- Move personalized skills to distinct directories before setup
When it happens
Trigger: Running agent-native setup when ~/.claude/skills/<name>/SKILL.md (or the codex equivalent) already exists from an older Caveman version with a different body, or was created by the user/another tool with the same name.
Common situations: Name collision between Caveman's agent-native suite and a user skill; leftover files from a manual install or a previous CLI version whose embedded bodies changed; a different product's skill with the same directory name.
Related errors
- ${skill.file} changed during interrupted setup; refusing des
- ${skill.file} changed during interrupted removal; refusing d
- ${profile.display_name} not found on PATH
- ${file} changed after setup; refusing to overwrite user skil
- Claude caveman-cloud MCP exists but is not Caveman-journaled
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/a3ddf29de09ee5ed.
Report an issue: GitHub.