JuliusBrussee/caveman · error
${path} already exists; refusing to overwrite an unjournaled
Error message
${path} already exists; refusing to overwrite an unjournaled plugin What it means
hermesNativeMutations() installs a Caveman plugin by creating plugin.yaml and __init__.py inside hermesNativePluginDir(). Unlike the config file, these plugin files carry no ownership marker, so ANY pre-existing file at those paths is treated as unjournaled third-party content and the install refuses to overwrite it.
Source
Thrown at packages/cli/src/index.ts:6775
owned: {
route: appendUrlPath(gw, "/w/hermes"),
route_block: routeBlock.join("\n"),
previous_route_lines: previousRouteLines,
plugin_block: pluginBlock,
mcp_block: mcpBlock,
},
};
}
function hermesNativeMutations(gw: string, mcpBinary: string): NativeMutation[] {
const configPath = hermesConfigPath();
const configBefore = fileBytes(configPath);
const native = hermesNativeConfig(configBefore?.toString("utf8") ?? "", gw, mcpBinary);
const pluginDir = hermesNativePluginDir();
const manifestPath = join(pluginDir, "plugin.yaml");
const initPath = join(pluginDir, "__init__.py");
for (const path of [manifestPath, initPath]) {
if (fileBytes(path)) throw new Error(`${path} already exists; refusing to overwrite an unjournaled plugin`);
}
return [
{ file: configPath, before: configBefore, after: Buffer.from(native.text), kind: "hermes-config", owned: native.owned },
{ file: manifestPath, before: null, after: Buffer.from(hermesNativePluginManifest()), kind: "hermes-plugin-manifest" },
{ file: initPath, before: null, after: Buffer.from(hermesNativePluginSource()), kind: "hermes-plugin-init" },
];
}
function withIntegrationLock<T>(agent: string, run: () => T): T {
const lock = join(cavemanHome(), "integrations", `.lock-${agent}`);
const ownerPath = join(lock, "owner.json");
const token = randomUUID();
mkdirSync(dirname(lock), { recursive: true, mode: 0o700 });
try { mkdirSync(lock, { recursive: false, mode: 0o700 }); }
catch (error) {
if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
let stale = false;
try {View on GitHub (pinned to 27d5a3981a)
Solutions
- Inspect both files; if they are leftovers or your own code, move them aside (mv plugin.yaml plugin.yaml.bak)
- If from a previous caveman install, delete them so the current install regenerates them
- Re-run the caveman hermes install
Example fix
# before $ ls ~/.hermes/plugins/caveman/ # plugin.yaml __init__.py already present Error: .../plugin.yaml already exists; refusing to overwrite an unjournaled plugin # after $ mv ~/.hermes/plugins/caveman ~/.hermes/plugins/caveman.bak $ caveman native install hermes # recreates manifest and __init__.py
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from "node:fs";
function hermesPluginPathsFree(dir: string): boolean {
return !existsSync(join(dir, "plugin.yaml")) && !existsSync(join(dir, "__init__.py"));
} Try / catch
try { nativeInstallHermes(); } catch (e) {
if (e instanceof Error && /refusing to overwrite an unjournaled plugin/.test(e.message)) {
backUpAndClearPluginDir(); nativeInstallHermes();
} else throw e;
} Prevention
- Check the plugin directory the installer uses before placing your own files there
- On upgrade failures, clear leftover generated plugin files rather than retrying blindly
- Keep personal plugins in differently-named directories
When it happens
Trigger: Native Hermes install when the Hermes plugin directory already contains a plugin.yaml or __init__.py file (any content, any origin).
Common situations: An earlier caveman version or aborted install left files behind; the user authored their own plugin at the same path; a different tool claimed the directory.
Related errors
- ${pluginPath} already exists and is not Caveman-owned; refus
- ${corePath} exists and is not exact Caveman-owned content; r
- cave_harness_aborted
- cave_vercel_terminal_failure
- caveman agent: invalid .caveman/provider.json
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/cb6e3654e41360f8.
Report an issue: GitHub.