BoundaryML/baml · error · std::io::Error
unit source path is not root-relative: `{rel}`
Error message
unit source path is not root-relative: `{rel}` What it means
The bytecode cache requires every unit's source_file to be a path relative to the package root, because manifest entries and cache keys are built from root-relative paths. When a unit's source_file is absolute for a file whose manifest key `rel` is relative, the two can never be reconciled, so storing is refused with InvalidData.
Source
Thrown at baml_language/crates/baml_cli/src/bytecode_cache.rs:1616
let pointer_plan = if reused_units { plan } else { None };
let mut unit_keys = HashMap::with_capacity(user_files.len());
let mut unit_entries_written = 0usize;
for (_, rel) in &user_files {
if let Some(key) = pointer_plan
.filter(|plan| plan.clean_files.contains(rel))
.and_then(|plan| plan.unit_keys.get(rel))
{
unit_keys.insert(rel.clone(), *key);
continue;
}
let Some(unit) = units_by_source.get(rel.as_str()) else {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("compiled output has no unit for `{rel}`"),
));
};
if std::path::Path::new(&unit.source_file).is_absolute() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("unit source path is not root-relative: `{rel}`"),
));
}
let (key, wrote) = self.cache.store_unit_shared(unit)?;
unit_entries_written += usize::from(wrote);
unit_keys.insert(rel.clone(), *key.as_bytes());
}
cache_debug(format_args!(
"unit store: wrote {unit_entries_written}, reused {}",
user_files.len().saturating_sub(unit_entries_written)
));
let mut files: Vec<ManifestFile> = Vec::with_capacity(user_files.len());
for (sf, rel) in user_files {
// The file's assembled unit carries its emit-recorded reference
// edges (`CompilationUnit::referenced_names` / `bakes_type_layout`)
// — recorded by codegen at its resolution sites, so direct callsView on GitHub (pinned to bd85ce9dee)
Solutions
- Register source files with paths relative to the package/source root (strip the root prefix before constructing the unit).
- Fix the caller that builds CompilationUnits to canonicalize against the project root rather than passing absolute paths.
- Check custom build scripts or CI wrappers that pass absolute paths for the baml sources.
- If caused by a library-internal path join, report it upstream with the platform and invocation.
Example fix
// before
CompilationUnit { source_file: "/home/user/proj/schema.baml", .. }
// after
CompilationUnit { source_file: "schema.baml", .. } // root-relative Defensive patterns
Strategy: validation
Validate before calling
for unit in &units {
if Path::new(&unit.source_file).is_absolute() {
return Err(format!("unit source must be root-relative: {}", unit.source_file));
}
} Type guard
fn is_root_relative(p: &str) -> bool {
!std::path::Path::new(p).is_absolute()
} Try / catch
match store_result {
Err(e) if e.to_string().contains("not root-relative") => {
eprintln!("fix source registration to use root-relative paths");
std::process::exit(1);
}
other => other?,
} Prevention
- Always construct CompilationUnit.source_file relative to the SourceRoot, never from env vars or absolute CLI args.
- Strip the project-root prefix (strip_prefix) before building units.
- Watch for Windows drive letters and leading '/' when porting build scripts.
- Add a debug assertion in unit assembly that rejects absolute paths early.
When it happens
Trigger: store_artifacts_with_manifest finds an assembled unit via units_by_source whose unit.source_file is an absolute path (e.g. a file was registered into the compile with its absolute filesystem path instead of the path relative to the SourceRoot).
Common situations: A build script or harness constructs CompilationUnits from absolute paths (e.g. from an env var or absolute CLI argument) instead of paths relative to the project root; a tool running on Windows/CI passes drive-letter absolute paths into the unit list.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- duplicate compilation unit for `{}`
- compiled output has no unit for `{rel}`
- BAML_CACHE_VERIFY: cached diagnostics for `{}` differ from a
- honest interface fragment for `{}` failed to serialize: {e}
- BAML_CACHE_VERIFY: cached interface fragment for `{}` differ
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/1b324688a2821d91.
Report an issue: GitHub.