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

  1. Delete (or back up and remove) the existing core file and re-run the enable command so Caveman writes a fresh copy.
  2. Run `caveman doctor aider` to detect and repair the stale core file.
  3. If you customized the core, save your changes elsewhere, delete the file, re-enable, then reapply customizations understanding they may be overwritten on upgrade.
  4. 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

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


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)