BoundaryML/baml · error · io::Error

blob path has no parent

Error message

blob path has no parent

What it means

BlobStore::write_blob calls Path::parent() on the target blob path and errors if it returns None. A canonical content-addressed path (<root>/<algorithm>/<2-hex>/<digest>.blob) always has a parent, so this is a defensive guard; it would only trigger for a degenerate path such as a bare relative filename with no directory components.

Solutions

  1. Initialize the store with a proper non-empty root via BlobStore::new or ::with_boundary_dir (e.g. <dir>/blobs).
  2. Ensure the root path is absolute or correctly relative to the working directory before writing blobs.
  3. If it occurs with a valid store, treat it as a bug — the library should never reach this with normal path_for() output.

Example fix

// before
let store = BlobStore::new("")?; // degenerate path
// after
let store = BlobStore::with_boundary_dir("/path/to/run_dir")?; // <dir>/blobs
Defensive patterns

Strategy: validation

Validate before calling

let root = Path::new(run_dir).join("blobs");
assert!(!root.as_os_str().is_empty(), "blob store root must be non-empty");
fs::create_dir_all(&root)?;

Try / catch

match store.write_blob(&blob_ref) {
    Ok(r) => r,
    Err(e) if e.kind() == io::ErrorKind::InvalidInput => {
        eprintln!("degenerate blob path — check BlobStore root: {e}");
        return Err(e.into());
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: write_blob() where the resolved blob path has no parent directory component — effectively only if the blob store root itself is empty/degenerate or the path was reduced to a single file name.

Common situations: Constructing a BlobStore with an empty or malformed root so the joined path collapses, or misusing internal APIs to bypass path_for().

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


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

Appendix: source

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

        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")
        })?;
        fs::create_dir_all(parent)?;
        let tmp_path = parent.join(format!(
            ".{}.{}.{}.tmp",
            blob_ref.digest,
            std::process::id(),
            uuid::Uuid::new_v4()
        ));
        {
            let mut tmp = OpenOptions::new()
                .write(true)
                .create_new(true)
                .open(&tmp_path)?;
            tmp.write_all(bytes)?;
            tmp.flush()?;
            tmp.sync_all()?;
        }
        if path.is_file() {

View on GitHub (pinned to bd85ce9dee)