JuliusBrussee/caveman · error · Error
native integration postflight is
Error message
${agent} native integration postflight is ${status.state} What it means
Thrown by verifyAgentNativeBundle during `caveman setup --agent-native` postflight when the native integration status for the agent (claude or codex) is anything other than "installed" after setup supposedly completed. The CLI verifies that the native integration actually took hold; if it didn't, the bundle verification fails loudly rather than leaving a half-configured agent.
Solutions
- Run `caveman setup --agent-native <agent>` again after fixing any write-permission issues so the install step can complete.
- Verify the agent binary/config exists (e.g. `claude --version`, check ~/.claude or ~/.codex) and install/update the agent if missing.
- Check nativeIntegrationStatus output for the agent to see the failing state and address the underlying cause (permissions, missing binary, unsupported agent version).
- Use `caveman setup --agent-native <agent> --remove` to clear partial state, then re-run setup.
Example fix
// before: setup proceeds even though agent binary absent $ caveman setup --agent-native claude // after: ensure agent is installed first $ claude --version || npm install -g @anthropic-ai/claude-code $ caveman setup --agent-native claude
Defensive patterns
Strategy: validation
Validate before calling
import { nativeIntegrationStatus } from "caveman/cli";
const status = nativeIntegrationStatus("claude");
if (status.state !== "installed") {
console.error(`native integration not ready: ${status.state}`);
process.exit(1);
} Try / catch
try {
verifyAgentNativeBundle(agent, journal, cloudMcp);
} catch (err) {
console.error(`postflight failed: ${(err as Error).message}. Re-run: caveman setup --agent-native ${agent}`);
process.exitCode = 1;
} Prevention
- Install/verify the agent CLI before running caveman setup.
- Run setup as the same user who owns the agent config directory.
- Avoid agent auto-updates racing with setup commands.
When it happens
Trigger: Running `caveman setup --agent-native claude` (or codex) where nativeIntegrationStatus(agent) returns a state like "not-installed", "partial", or "error" immediately after the install step — e.g. the agent's config file was not written or the native marker is missing.
Common situations: Agent CLI not installed or upgraded to an incompatible version that moved its config location; read-only home directory preventing config writes; a prior failed setup left partial state; running as a different user than the one whose config was modified.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- caveman-cloud MCP postflight mismatch
- caveman-cloud MCP registration failed exact postflight
- agent-native setup failed
- caveman-mcp lacks current mcp_recovery capability; run…
- caveman-proxy not found; run `caveman setup --install`
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/308c7d07d03af8f9.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:2906
}
}
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 3ee70a1026)