{"record":{"id":"1a543fc97c771ad3","repo":"astrid-runtime/astrid","slug":"distro-lock-capsule-capsule-content-blob-bytes","errorCode":null,"errorMessage":"Distro.lock capsule '{capsule}' content blob bytes do not match hash {locked_hash}","messagePattern":"Distro\\.lock capsule '(.+?)' content blob bytes do not match hash (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/astrid-cli/src/commands/init_grant.rs","lineNumber":419,"sourceCode":"            .map_err(|error| anyhow::anyhow!(error))?\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Distro.lock capsule '{capsule}' catalog entry has no readable bytes: bin/{locked_hex}.wasm\"\n                )\n            })?\n    } else {\n        let blob_path = home.bin_dir().join(format!(\"{locked_hex}.wasm\"));\n        std::fs::read(&blob_path).with_context(|| {\n            format!(\n                \"Distro.lock capsule '{}' content blob is missing or unreadable at {}\",\n                capsule,\n                blob_path.display()\n            )\n        })?\n    };\n    let actual = blake3::hash(&bytes);\n    if actual != locked {\n        bail!(\"Distro.lock capsule '{capsule}' content blob bytes do not match hash {locked_hash}\");\n    }\n    Ok(())\n}\n\nfn parse_locked_blake3(capsule: &CapsuleId, value: &str) -> anyhow::Result<blake3::Hash> {\n    let Some(hex) = value.strip_prefix(\"blake3:\") else {\n        bail!(\"Distro.lock capsule '{capsule}' requires a canonical blake3:<hex> WASM hash\");\n    };\n    let hash = blake3::Hash::from_hex(hex).map_err(|_| {\n        anyhow::anyhow!(\"Distro.lock capsule '{capsule}' has an invalid BLAKE3 hash\")\n    })?;\n    if hex.len() != 64 || hash.to_hex().as_str() != hex {\n        bail!(\"Distro.lock capsule '{capsule}' requires a canonical lowercase BLAKE3 hash\");\n    }\n    Ok(hash)\n}\n\nfn manifest_declares_wasm(manifest: &CapsuleManifest) -> bool {","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init_grant.rs#L401-L437","documentation":"As the final integrity check, the CLI hashes the actual content blob backing the capsule (from the runtime principal store or the blob path) and requires it to equal the locked blake3 hash. If the bytes differ, the stored artifact is corrupt or substituted and validation bails.","triggerScenarios":"validate_locked_wasm loads the blob bytes, computes blake3::hash(&bytes), and the result != locked hash parsed from the lockfile.","commonSituations":"Corrupted or truncated blob in the content store, blob overwritten by another build, disk corruption, or content-addressed file bin/{hex}.wasm replaced manually.","solutions":["Reinstall the capsule to rewrite the content blob from a trusted source.","Restore the blob bin/{locked_hex}.wasm from a verified artifact so its bytes hash to the locked value.","Regenerate Distro.lock if the new artifact is intentionally the one to trust.","Check storage/disk health if blobs are repeatedly corrupting."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let bytes = std::fs::read(&blob_path)?;\nlet actual = blake3::hash(&bytes);\nif actual.to_hex().as_str() != locked_hex {\n    return Err(anyhow!(\"blob corruption for {}\", capsule));\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = validate_lock(&lock) {\n    if e.to_string().contains(\"bytes do not match hash\") {\n        restore_blob_from_trusted_source(capsule).await?;\n    } else { return Err(e.into()); }\n}","preventionTips":["Never modify files under the content-addressed store (bin/{hex}.wasm).","Verify artifact hashes after copying blobs between machines.","Monitor storage health; re-fetch from origin on any corruption."],"tags":["checksum-mismatch","integrity","wasm","storage"],"backgroundTag":"checksum-mismatch","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}