{"record":{"id":"308c7d07d03af8f9","repo":"JuliusBrussee/caveman","slug":"agent-native-integration-postflight-is-status","errorCode":null,"errorMessage":"${agent} native integration postflight is ${status.state}","messagePattern":"(.+?) native integration postflight is (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2586,"sourceCode":"  }\n}\n\nfunction installAgentNativeBundleSkills(agent: \"claude\" | \"codex\", journal: AgentNativeBundleJournal): void {\n  const originals = new Map(journal.skills.map((skill) => [skill.file, skill.before_base64]));\n  journal.skills = agentNativeSkillFiles(agent).map(({ file, body }) => {\n    mkdirSync(dirname(file), { recursive: true });\n    atomicWriteFile(file, Buffer.from(body));\n    return {\n      file,\n      before_base64: originals.get(file) ?? null,\n      after_sha256: bytesHash(Buffer.from(body)),\n    };\n  });\n}\n\nfunction verifyAgentNativeBundle(agent: \"claude\" | \"codex\", journal: AgentNativeBundleJournal, cloudMcp: { command: string; args: string[] }): void {\n  const status = nativeIntegrationStatus(agent);\n  if (status.state !== \"installed\") throw new Error(`${agent} native integration postflight is ${status.state}`);\n  const marker = readMcpServerMarker(agent, \"caveman-cloud\");\n  if (!marker || marker.command !== cloudMcp.command || JSON.stringify(marker.args) !== JSON.stringify(cloudMcp.args)) {\n    throw new Error(`${agent} caveman-cloud MCP postflight mismatch`);\n  }\n  if (!agentNativeCloudMcpMatches(agent, cloudMcp)) {\n    throw new Error(`${agent} caveman-cloud MCP registration failed exact postflight`);\n  }\n  for (const skill of journal.skills) {\n    const current = fileBytes(skill.file);\n    if (!current || bytesHash(current) !== skill.after_sha256) throw new Error(`${skill.file} failed skill postflight`);\n  }\n}\n\nfunction removeAgentNativeBundle(agent: \"claude\" | \"codex\"): void {\n  recoverPendingAgentNativeRemoval(agent);\n  recoverPendingAgentNativeBundle(agent);\n  const journal = readAgentNativeBundleJournal(agent);\n  if (!journal) {","sourceCodeStart":2568,"sourceCodeEnd":2604,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/index.ts#L2568-L2604","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-run `caveman setup --agent-native <agent>` after removing prior state with `caveman setup --agent-native <agent> --remove` so the native layer starts clean","Inspect the agent's native config location (~/.claude.json / ~/.codex config) for partial writes or permission errors and fix them","Check that no other caveman session is concurrently modifying native integration state","Update the caveman CLI so the status probe and installer agree on the same integration schema"],"exampleFix":"# before\n caveman setup --agent-native claude   # fails: postflight is \"configured\"\n\n# after\ncaveman setup --agent-native claude --remove\ncaveman setup --agent-native claude","handlingStrategy":"try-catch","validationCode":"import { nativeIntegrationStatus } from \"caveman\";\n// before triggering setup, check current state\nconst status = nativeIntegrationStatus(\"claude\");\nif (status.state !== \"absent\" && status.state !== \"installed\") {\n  // normalize first: remove stale native state\n  console.error(`native state is ${status.state}; run caveman setup --agent-native claude --remove first`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await setup([\"--agent-native\", \"claude\"]);\n} catch (error) {\n  if (/native integration postflight is/.test((error as Error).message)) {\n    // state machine issue, not transient: clean re-install path\n    await setup([\"--agent-native\", \"claude\", \"--remove\"]).catch(() => {});\n    await setup([\"--agent-native\", \"claude\"]);\n  } else throw error;\n}","preventionTips":["Always pair --remove with re-setup when normalizing agent-native state instead of patching config by hand","Close the target agent before running agent-native setup so nothing rewrites state mid-flight","Keep the CLI and installed Go binaries at the same version"],"tags":["postflight","agent-native","setup","verification"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}