{"record":{"id":"83ec67a2db904552","repo":"BoundaryML/baml","slug":"blob-digest-mismatch-for-computed","errorCode":null,"errorMessage":"blob digest mismatch for {}; computed {}","messagePattern":"blob digest mismatch for (.+?); computed (.+?)","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_events/src/value/artifact.rs","lineNumber":82,"sourceCode":"        self.validate()?;\n        Ok(self.digest.to_ascii_lowercase())\n    }\n\n    fn verify_bytes(&self, bytes: &[u8]) -> io::Result<()> {\n        if bytes.len() != self.size_bytes {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"blob size mismatch for {}; expected {} bytes, got {} bytes\",\n                    self.digest,\n                    self.size_bytes,\n                    bytes.len()\n                ),\n            ));\n        }\n        let actual = Self::sha256(bytes);\n        if actual.digest != self.digest.to_ascii_lowercase() {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"blob digest mismatch for {}; computed {}\",\n                    self.digest, actual.digest\n                ),\n            ));\n        }\n        Ok(())\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct BlobStore {\n    root: PathBuf,\n}\n\nimpl BlobStore {\n    #[must_use]","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_events/src/value/artifact.rs#L64-L100","documentation":"After the size check, BlobStore::verify_bytes computes SHA-256 over the read bytes and compares it to the BlobRef's normalized (lowercase) digest. This error means the blob content on disk does not hash to the recorded digest — the content is not what the reference claims. It is an io::Error with InvalidData kind raised from read_blob.","triggerScenarios":"read_blob() on a blob whose file bytes were modified after writing (corruption, partial overwrite, wrong file promoted over the content-addressed path).","commonSituations":"Hardware/filesystem corruption, manual edits or copy operations clobbering files under the blobs/ directory, collisions from mishandled temp files, or referencing a blob by a digest computed from different content.","solutions":["Delete the mismatching blob file and re-write it from the original source bytes via write_blob().","Verify the BlobRef digest against the original content (sha256sum) — if the reference is wrong, regenerate it from the actual bytes.","Restore the blob store from backup and re-run any processing that consumed the corrupt artifact."],"exampleFix":"// before\nlet bytes = store.read_blob(&stale_ref)?; // digest mismatch\n// after\nlet mut real_ref = BlobRef::sha256(original_bytes);\nstore.write_blob(&real_ref)?;\nlet bytes = store.read_blob(&real_ref)?;","handlingStrategy":"try-catch","validationCode":"let expected = blob_ref.normalized_digest()?;\nlet actual = hex::encode(Sha256::digest(&original_bytes));\nif expected != actual.to_lowercase() { /* reference is stale; regenerate */ }","typeGuard":null,"tryCatchPattern":"let bytes = match store.read_blob(&blob_ref) {\n    Ok(b) => b,\n    Err(e) if e.to_string().contains(\"digest mismatch\") => {\n        // content corrupted: re-write from authoritative source\n        store.write_blob(&BlobRef::sha256(&source_bytes))?;\n        store.read_blob(&blob_ref)?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Treat the blob store directory as immutable content-addressed storage — no external writes.","Keep authoritative source data so blobs can be re-derived on corruption.","Back up the blob store and verify integrity periodically with a sweep of read_blob()."],"tags":["rust","blob-storage","integrity","checksum"],"backgroundTag":"checksum-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}