{"record":{"id":"68b92f87c0fbf0d4","repo":"Hmbown/CodeWhale","slug":"installed-package-failed-content-digest-validation","errorCode":null,"errorMessage":"installed package failed content digest validation: {err}","messagePattern":"installed package failed content digest validation: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/skills/install.rs","lineNumber":377,"sourceCode":"        if let Some(parent) = final_path.parent() {\n            fs::create_dir_all(parent).with_context(|| {\n                format!(\"failed to create skills directory {}\", parent.display())\n            })?;\n        }\n        fs::rename(&staged.staged_path, &final_path).context(\"failed to install staged skill\")?;\n    }\n\n    // Write the marker last so a partial install never leaves a stale\n    // .installed-from on disk. Prefer v2 with package content digest.\n    let spec = source_spec_string(&source);\n    let content_digest = match super::package_digest::compute_package_digest(&final_path) {\n        Ok(digest) => digest,\n        Err(err) => {\n            let _ = fs::remove_dir_all(&final_path);\n            if let Some(backup) = backup_path.take() {\n                let _ = fs::rename(&backup, &final_path);\n            }\n            return Err(anyhow::anyhow!(\n                \"installed package failed content digest validation: {err}\"\n            ));\n        }\n    };\n    if let Err(err) = write_installed_from_v2(\n        &final_path,\n        &spec,\n        Some(&source_url),\n        &checksum,\n        &content_digest,\n        &staged.skill_name,\n    ) {\n        let _ = fs::remove_dir_all(&final_path);\n        if let Some(backup) = backup_path.take() {\n            let _ = fs::rename(&backup, &final_path);\n        }\n        return Err(err);\n    }","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/skills/install.rs#L359-L395","documentation":"At the end of a skill-package install, the installer computes a content digest over the installed tree (compute_package_digest on final_path) so the .installed-from v2 marker can pin it. If digest computation itself fails (the wrapped {err}), the install is rolled back: final_path is removed, any pre-existing backup directory is renamed back into place, and this error is returned. It signals a filesystem-level failure while walking/reading the just-installed package, not a mismatch against an expected checksum.","triggerScenarios":"compute_package_digest fails while walking final_path: a file becomes unreadable mid-walk (permissions changed), the tree is mutated concurrently by another install of the same skill, a path disappears between staging and digest, or an I/O error (full disk, failing drive, AV/lock interference) occurs.","commonSituations":"Two installs racing into the same skills directory; antivirus or file locks on Windows touching freshly written files; disk-full during a large package install; a watcher process pruning skill files as they land.","solutions":["Read the wrapped {err} — it names the exact file and I/O cause.","Ensure no concurrent installs target the same skill (serialize installs or re-run the install once the other finishes).","Check disk space and directory permissions on the skills root.","On Windows, exclude the skills directory from antivirus scanning or pause watchers, then reinstall."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match install_skill(&source) {\n    Ok(_) => {}\n    Err(e) if e.to_string().contains(\"content digest validation\") => {\n        // install was rolled back; inspect underlying cause, clear contention, retry once\n        log::warn!(\"skill install rolled back: {e:#}\");\n        std::thread::sleep(std::time::Duration::from_secs(1));\n        install_skill(&source)?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Serialize installs of the same skill — never run two installers against one skills directory at once.","Keep the skills root writable and off paths scanned by antivirus/sync agents.","Ensure adequate disk space before installing large skill packages."],"tags":["skills","install","digest","integrity","filesystem"],"backgroundTag":"package-integrity-check-failed","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}