BoundaryML/baml · error · io::Error
.bamlvalue header boundary id must be 16 bytes, got {}
Error message
.bamlvalue header boundary id must be 16 bytes, got {} What it means
boundary_id_from_header converts the 16-byte boundary ID stored in a .bamlvalue file header into a [u8; 16] BoundaryId; if the header field is any other length, InvalidData is returned with the actual byte count. This guards against corrupt, truncated, or hand-written segment headers.
Source
Thrown at baml_language/crates/bex_events/src/history/mod.rs:638
),
));
}
fallback_dir
.and_then(boundary_id_from_dir_name)
.ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidData,
format!(
"history boundary for project {} omitted canonical boundary id",
started.request.project_id.0
),
)
})
}
fn boundary_id_from_header(bytes: &[u8]) -> io::Result<BoundaryId> {
let bytes: [u8; 16] = bytes.try_into().map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
format!(
".bamlvalue header boundary id must be 16 bytes, got {}",
bytes.len()
),
)
})?;
Ok(BoundaryId::from_bytes(bytes))
}
fn boundary_id_from_dir_name(dir: &Path) -> Option<BoundaryId> {
let name = dir.file_name()?.to_str()?;
name.char_indices()
.rev()
.find_map(|(index, _)| BoundaryId::from_wire_str(&name[index..]))
}
fn capture_loss_replay_diagnostic(record: CaptureLossRecord) -> RunDiagnostic {View on GitHub (pinned to bd85ce9dee)
Solutions
- Regenerate the .bamlvalue segments with the current library version so headers are well-formed.
- Check whether the file was truncated (compare size with the writer's expectation) and re-record if so.
- Ensure all producers and consumers of history files use the same bex_events version.
- Don't hand-edit segment files; craft test segments via the library's writer APIs.
Example fix
// before
let id = boundary_id_from_header(header_bytes)?;
// after
if header_bytes.len() != 16 {
eprintln!("corrupt .bamlvalue header ({} bytes), re-recording", header_bytes.len());
return re_record();
}
let id = boundary_id_from_header(header_bytes)?; Defensive patterns
Strategy: validation
Validate before calling
if header_bytes.len() != 16 {
return Err(format!(
".bamlvalue header boundary id is {} bytes, expected 16",
header_bytes.len()
));
} Type guard
fn is_valid_header(bytes: &[u8]) -> bool {
bytes.len() >= 16
} Try / catch
match boundary_id_from_header(header_bytes) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
Err(ArtifactError::CorruptHeader)
}
other => other,
} Prevention
- Use the same bex_events version for writers and readers of .bamlvalue files.
- Detect truncated files by size before parsing headers.
- Never hand-edit binary segment files; build test fixtures via the writer API.
When it happens
Trigger: open_boundary_from_segments reading a .bamlvalue file whose header boundary-id field is not exactly 16 bytes — produced by an older/newer writer format, truncation, or manual file editing.
Common situations: Mixed bex_events versions writing incompatible header layouts; partially written files after a crash; tests crafting malformed byte segments directly.
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
- history boundary {} omitted run started record
- history boundary {} has inconsistent value segment boundary
- history boundary for project {} omitted canonical boundary i
- history boundary {} was not begun
- history boundary {} was not found
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/d418efd013845881.
Report an issue: GitHub.