{"record":{"id":"75f190639ed9fd92","repo":"JuliusBrussee/caveman","slug":"skill-file-failed-skill-postflight","errorCode":null,"errorMessage":"${skill.file} failed skill postflight","messagePattern":"(.+?) failed skill postflight","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2916,"sourceCode":"      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) {\n    process.stderr.write(`${mark(\"warn\")} ${agent}: no agent-native bundle journal found\\n`);\n    return;\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} changed after setup; refusing destructive bundle removal`);\n  }\n  const marker = readMcpServerMarker(agent, \"caveman-cloud\");\n  if (!sameMcpCommand(marker, journal.cloud_mcp) || !agentNativeCloudMcpMatches(agent, journal.cloud_mcp)) {\n    throw new Error(`${agent} caveman-cloud MCP changed after setup; refusing destructive bundle removal`);","sourceCodeStart":2898,"sourceCodeEnd":2934,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L2898-L2934","documentation":"Thrown at the end of verifyAgentNativeBundle when a skill file recorded in the agent-native bundle journal is missing or its hash no longer equals the after_sha256 captured at setup. It certifies that every delivered skill file is still intact right after installation.","triggerScenarios":"During setup postflight, fileBytes(skill.file) returns nothing (file deleted) or bytesHash(current) !== skill.after_sha256 — e.g. the file was overwritten between write and verification, or the write silently failed.","commonSituations":"Antivirus or sync tools (Dropbox/iCloud) modified or locked the skill file immediately after writing; two setup runs raced; disk-full truncated the file; the agent overwrote its skills directory on startup.","solutions":["Re-run `caveman setup --agent-native <agent>` to rewrite the skill files and re-verify.","Exclude the agent's config/skills directories from file-sync or antivirus real-time scanning.","Check for concurrent caveman/agent processes and ensure only one setup runs at a time.","Verify free disk space and filesystem writability for the skills directory."],"exampleFix":"// before: sync tool rewrites files mid-setup\n~/Library/CloudStorage/... synced skills dir\n// after: relocate agent config out of synced storage or pause sync during setup\n$ caveman setup --agent-native claude","handlingStrategy":"validation","validationCode":"const current = fileBytes(skill.file);\nif (!current || bytesHash(current) !== skill.after_sha256) {\n  console.error(`${skill.file} missing or modified; re-run setup`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  verifyAgentNativeBundle(agent, journal, cloudMcp);\n} catch (err) {\n  if (/failed skill postflight/.test((err as Error).message)) {\n    console.error(\"Skill file changed during setup; re-running\");\n  }\n}","preventionTips":["Exclude agent config/skills directories from file-sync and antivirus scanning.","Run only one caveman setup at a time.","Ensure adequate disk space before setup."],"tags":["postflight","integrity","checksum-mismatch","skills","cli"],"backgroundTag":"checksum-mismatch","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}