{"record":{"id":"488867ea54ea7cde","repo":"BoundaryML/baml","slug":"invalid-sha256-blob-digest-length-expected-hex-characters","errorCode":null,"errorMessage":"invalid sha256 blob digest length {}; expected {} hex characters","messagePattern":"invalid sha256 blob digest length (.+?); expected (.+?) hex characters","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_events/src/value/artifact.rs","lineNumber":45,"sourceCode":"        for byte in digest {\n            let _ = write!(&mut hex, \"{byte:02x}\");\n        }\n        Self {\n            algorithm: Self::ALGORITHM_SHA256.to_string(),\n            digest: hex,\n            size_bytes: bytes.len(),\n        }\n    }\n\n    pub fn validate(&self) -> io::Result<()> {\n        if self.algorithm != Self::ALGORITHM_SHA256 {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\"unsupported blob algorithm `{}`\", self.algorithm),\n            ));\n        }\n        if self.digest.len() != Self::SHA256_HEX_LEN {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"invalid sha256 blob digest length {}; expected {} hex characters\",\n                    self.digest.len(),\n                    Self::SHA256_HEX_LEN\n                ),\n            ));\n        }\n        if !self.digest.bytes().all(|byte| byte.is_ascii_hexdigit()) {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"invalid sha256 blob digest; expected only hex characters\",\n            ));\n        }\n        Ok(())\n    }\n\n    fn normalized_digest(&self) -> io::Result<String> {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_events/src/value/artifact.rs#L27-L63","documentation":"BlobRef::validate checks that a sha256 blob digest is exactly SHA256_HEX_LEN (64) hex characters long. This error fires when the stored digest string has a different length, meaning the blob reference is malformed and cannot correspond to a real SHA-256 hash. It is returned as an io::Error with InvalidData kind from normalized_digest and all blob read/write paths.","triggerScenarios":"Constructing or deserializing a BlobRef whose digest string length != 64 (e.g. a truncated, empty, or base64-encoded digest), then calling normalized_digest(), write_blob(), read_blob(), or path_for().","commonSituations":"Manually editing event/bundle files, copying digests with surrounding whitespace stripped incorrectly or truncated in logs, using a different hash algorithm (e.g. sha1, 40 hex chars) while still declaring algorithm=sha256, or hand-crafting BlobRef values in tests/tools.","solutions":["Recompute the digest with SHA-256 over the blob bytes and store the full 64-character lowercase hex string.","Check the digest string for truncation or accidental whitespace/newlines; trim nothing away and verify len == 64.","If the digest came from another tool, confirm it emits sha256 hex and not base64 or a different algorithm; fix the algorithm field accordingly."],"exampleFix":"// before\nlet blob_ref = BlobRef { algorithm: \"sha256\", digest: short_digest.to_string(), .. };\n// after\nassert_eq!(digest.len(), 64);\nlet blob_ref = BlobRef { algorithm: \"sha256\", digest: full_sha256_hex(blob_bytes), .. };","handlingStrategy":"validation","validationCode":"fn valid_sha256_hex(digest: &str) -> bool {\n    digest.len() == 64 && digest.bytes().all(|b| b.is_ascii_hexdigit())\n}\nif !valid_sha256_hex(&blob_ref.digest) { /* fix or recompute digest before use */ }","typeGuard":"fn is_sha256_digest(s: &str) -> bool { s.len() == 64 && s.bytes().all(|b| b.is_ascii_hexdigit()) }","tryCatchPattern":"match blob_ref.normalized_digest() {\n    Ok(digest) => { /* proceed */ }\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => eprintln!(\"bad blob ref: {e}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Always generate digests via the library's BlobRef::sha256 helper instead of hand-building strings.","Store digests as lowercase hex of exactly 64 characters; add a unit assertion where digests are created.","Never truncate digests for display and then reuse the shortened string as a reference."],"tags":["rust","validation","blob-storage","checksum"],"backgroundTag":"invalid-argument-format","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"}