JuliusBrussee/caveman · error

${agent} native integration postflight is ${status.state}

Error message

${agent} native integration postflight is ${status.state}

What it means

Thrown by verifyAgentNativeBundle after installing an agent-native bundle for claude or codex. After setup completes, nativeIntegrationStatus(agent) must report "installed"; any other state (e.g. "configured", "missing", "disabled") means the native integration layer did not reach the installed state. This is a postflight check: setup wrote files but the resulting integration state does not verify.

Source

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

  }
}

function installAgentNativeBundleSkills(agent: "claude" | "codex", journal: AgentNativeBundleJournal): void {
  const originals = new Map(journal.skills.map((skill) => [skill.file, skill.before_base64]));
  journal.skills = agentNativeSkillFiles(agent).map(({ file, body }) => {
    mkdirSync(dirname(file), { recursive: true });
    atomicWriteFile(file, Buffer.from(body));
    return {
      file,
      before_base64: originals.get(file) ?? null,
      after_sha256: bytesHash(Buffer.from(body)),
    };
  });
}

function verifyAgentNativeBundle(agent: "claude" | "codex", journal: AgentNativeBundleJournal, cloudMcp: { command: string; args: string[] }): void {
  const status = nativeIntegrationStatus(agent);
  if (status.state !== "installed") throw new Error(`${agent} native integration postflight is ${status.state}`);
  const marker = readMcpServerMarker(agent, "caveman-cloud");
  if (!marker || marker.command !== cloudMcp.command || JSON.stringify(marker.args) !== JSON.stringify(cloudMcp.args)) {
    throw new Error(`${agent} caveman-cloud MCP postflight mismatch`);
  }
  if (!agentNativeCloudMcpMatches(agent, cloudMcp)) {
    throw new Error(`${agent} caveman-cloud MCP registration failed exact postflight`);
  }
  for (const skill of journal.skills) {
    const current = fileBytes(skill.file);
    if (!current || bytesHash(current) !== skill.after_sha256) throw new Error(`${skill.file} failed skill postflight`);
  }
}

function removeAgentNativeBundle(agent: "claude" | "codex"): void {
  recoverPendingAgentNativeRemoval(agent);
  recoverPendingAgentNativeBundle(agent);
  const journal = readAgentNativeBundleJournal(agent);
  if (!journal) {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Re-run `caveman setup --agent-native <agent>` after removing prior state with `caveman setup --agent-native <agent> --remove` so the native layer starts clean
  2. Inspect the agent's native config location (~/.claude.json / ~/.codex config) for partial writes or permission errors and fix them
  3. Check that no other caveman session is concurrently modifying native integration state
  4. Update the caveman CLI so the status probe and installer agree on the same integration schema

Example fix

# before
 caveman setup --agent-native claude   # fails: postflight is "configured"

# after
caveman setup --agent-native claude --remove
caveman setup --agent-native claude
Defensive patterns

Strategy: try-catch

Validate before calling

import { nativeIntegrationStatus } from "caveman";
// before triggering setup, check current state
const status = nativeIntegrationStatus("claude");
if (status.state !== "absent" && status.state !== "installed") {
  // normalize first: remove stale native state
  console.error(`native state is ${status.state}; run caveman setup --agent-native claude --remove first`);
}

Try / catch

try {
  await setup(["--agent-native", "claude"]);
} catch (error) {
  if (/native integration postflight is/.test((error as Error).message)) {
    // state machine issue, not transient: clean re-install path
    await setup(["--agent-native", "claude", "--remove"]).catch(() => {});
    await setup(["--agent-native", "claude"]);
  } else throw error;
}

Prevention

When it happens

Trigger: Running `caveman setup --agent-native claude|codex` (or the programmatic setup path) where the native integration steps partially failed: native config write succeeded but the enable/install phase errored, or the status probe reads a different state after writes. Any state value other than the literal string "installed" right after bundle installation triggers it.

Common situations: Native config directory (~/.claude or ~/.codex) is read-only or partially written; a concurrent session disabled native integration mid-setup; a stale or corrupted native journal makes status report a non-installed state; version skew between CLI and previously installed native files.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/308c7d07d03af8f9. Report an issue: GitHub.