BoundaryML/baml · error · io::Error

blob digest mismatch for {}; computed {}

Error message

blob digest mismatch for {}; computed {}

What it means

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.

Source

Thrown at baml_language/crates/bex_events/src/value/artifact.rs:82

        self.validate()?;
        Ok(self.digest.to_ascii_lowercase())
    }

    fn verify_bytes(&self, bytes: &[u8]) -> io::Result<()> {
        if bytes.len() != self.size_bytes {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "blob size mismatch for {}; expected {} bytes, got {} bytes",
                    self.digest,
                    self.size_bytes,
                    bytes.len()
                ),
            ));
        }
        let actual = Self::sha256(bytes);
        if actual.digest != self.digest.to_ascii_lowercase() {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "blob digest mismatch for {}; computed {}",
                    self.digest, actual.digest
                ),
            ));
        }
        Ok(())
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BlobStore {
    root: PathBuf,
}

impl BlobStore {
    #[must_use]

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Delete the mismatching blob file and re-write it from the original source bytes via write_blob().
  2. Verify the BlobRef digest against the original content (sha256sum) — if the reference is wrong, regenerate it from the actual bytes.
  3. Restore the blob store from backup and re-run any processing that consumed the corrupt artifact.

Example fix

// before
let bytes = store.read_blob(&stale_ref)?; // digest mismatch
// after
let mut real_ref = BlobRef::sha256(original_bytes);
store.write_blob(&real_ref)?;
let bytes = store.read_blob(&real_ref)?;
Defensive patterns

Strategy: try-catch

Validate before calling

let expected = blob_ref.normalized_digest()?;
let actual = hex::encode(Sha256::digest(&original_bytes));
if expected != actual.to_lowercase() { /* reference is stale; regenerate */ }

Try / catch

let bytes = match store.read_blob(&blob_ref) {
    Ok(b) => b,
    Err(e) if e.to_string().contains("digest mismatch") => {
        // content corrupted: re-write from authoritative source
        store.write_blob(&BlobRef::sha256(&source_bytes))?;
        store.read_blob(&blob_ref)?
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: read_blob() on a blob whose file bytes were modified after writing (corruption, partial overwrite, wrong file promoted over the content-addressed path).

Common situations: 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.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/83ec67a2db904552. Report an issue: GitHub.