JuliusBrussee/caveman · error · Error

cannot persist ${agentId} ${serverName} MCP ownership journa

Error message

cannot persist ${agentId} ${serverName} MCP ownership journal at ${path}: ${(error as Error).message}

What it means

Failure of the ownership-journal preflight: before touching the agent's native MCP config, the code proves it can create and remove the journal file under cavemanHome()/mcp. If persisting the journal fails (permissions, full disk, unreadable directory), the write is aborted because the registration and its journal must commit together.

Source

Thrown at packages/cli/src/index.ts:10292

  return canonicalMcpConfigPath(path);
}

// A native MCP registration and its Caveman ownership journal form one logical
// write. Prove the journal directory is writable before touching agent config;
// otherwise Kilo/Qwen would refuse both a later upgrade and removal because the
// surviving registration has no trustworthy owner.
function preflightMcpServerMarker(agentId: string, serverName: string): void {
  const path = mcpServerMarkerPath(agentId, serverName);
  const probe = join(dirname(path), `.${basename(path)}.preflight-${process.pid}-${randomUUID()}`);
  try {
    mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
    chmodSync(dirname(path), 0o700);
    durableAtomicWriteFile(probe, Buffer.alloc(0));
    unlinkSync(probe);
    fsyncParentDirectory(probe);
  } catch (error) {
    try { unlinkSync(probe); } catch { /* no probe survived */ }
    throw new Error(`cannot persist ${agentId} ${serverName} MCP ownership journal at ${path}: ${(error as Error).message}`);
  }
}
function mcpMarkerPath(agentId: string): string {
  return mcpServerMarkerPath(agentId, "caveman");
}
function mcpServerInstalled(agentId: string, serverName: string): boolean {
  try {
    return statSync(mcpServerMarkerPath(agentId, serverName)).isFile();
  } catch {
    return false;
  }
}
function mcpInstalled(agentId: string, agentArgs: string[] = []): boolean {
  if (agentId === "kilo" || agentId === "qwen") return ownedMcpRegistration(agentId, agentArgs) !== null;
  return mcpServerInstalled(agentId, "caveman");
}

// configFileOverlayHasMcp asks whether the PROFILE would inject this MCP server

View on GitHub (pinned to 5184b3d11a)

Solutions

  1. Fix filesystem permissions on the cavemanHome()/mcp directory so the journal can be created
  2. Free disk space or repair the underlying I/O error reported in the message
  3. Set CAVE_HOME (or the equivalent home override) to a writable location and retry the MCP install
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at packages/cli/src/index.ts:10292 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-09-06). Data as JSON: /api/errors/5a19e1df6056fe09. Report an issue: GitHub.