BoundaryML/baml · error · io::Error
blob digest has no prefix
Error message
blob digest has no prefix
What it means
BlobStore::path_for sharding uses the first two hex characters of the normalized digest as a subdirectory prefix. This error fires when slicing digest[..2] fails, i.e. the digest has fewer than 2 characters. In practice validate() (length 64, hex only) runs first, so this is a defensive internal invariant guard.
Solutions
- Ensure the digest passes normalized_digest() before computing the path; fix the caller to call validate().
- Check that the BlobRef construction path produces the full 64-char digest, not an empty string.
- If this appears with valid digests, report it — it indicates an internal invariant violation in the library.
Example fix
// before let prefix = digest.get(..2).ok_or(...)?; // reached with digest.len() < 2 // after let digest = blob_ref.normalized_digest()?; // validates len==64 + hex first let prefix = &digest[..2];
Defensive patterns
Strategy: validation
Validate before calling
let digest = blob_ref.normalized_digest()?; // panics-free guard: validates len 64 + hex before path math debug_assert!(digest.len() >= 2);
Type guard
fn has_prefix(digest: &str) -> bool { digest.len() >= 2 } Try / catch
let path = store.path_for(&blob_ref).map_err(|e| {
eprintln!("cannot resolve blob path: {e}");
e
})?; Prevention
- Always call normalized_digest()/validate() before using a BlobRef in path computations.
- Use the public BlobStore API (write_blob/read_blob) instead of hand-assembling paths.
When it happens
Trigger: path_for() with a BlobRef whose digest is shorter than 2 characters — only possible if validate/normalized_digest were bypassed or a new code path constructs the store without calling normalized_digest.
Common situations: Custom or forked code paths calling path_for with an unvalidated BlobRef, or regressions after refactoring validation order.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- blob path has no parent
- blob digest mismatch for
- blob size mismatch for
- block aware tail expression is not empty
- exhaustive realized-leaf template classification
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/2ee5557ac5ab499a.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/bex_events/src/value/artifact.rs:115
}
impl BlobStore {
#[must_use]
pub fn new(root: impl AsRef<Path>) -> Self {
Self {
root: root.as_ref().to_path_buf(),
}
}
#[must_use]
pub fn for_boundary_dir(boundary_dir: impl AsRef<Path>) -> Self {
Self::new(boundary_dir.as_ref().join("blobs"))
}
pub fn path_for(&self, blob_ref: &BlobRef) -> io::Result<PathBuf> {
let digest = blob_ref.normalized_digest()?;
let prefix = digest.get(..2).ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidData, "blob digest has no prefix")
})?;
Ok(self
.root
.join(&blob_ref.algorithm)
.join(prefix)
.join(format!("{digest}.blob")))
}
pub fn write_blob(&self, bytes: &[u8]) -> io::Result<BlobRef> {
let blob_ref = BlobRef::sha256(bytes);
let path = self.path_for(&blob_ref)?;
if path.is_file() {
return Ok(blob_ref);
}
let parent = path.parent().ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, "blob path has no parent")
})?;View on GitHub (pinned to bd85ce9dee)