BoundaryML/baml · error
boundary id must be 16 bytes, got
Error message
boundary id must be 16 bytes, got {} What it means
boundary_id_from_slice requires the input byte slice to be exactly 16 bytes to build a BoundaryId (a 128-bit identifier, likely a UUID). Any other length is rejected with io::ErrorKind::InvalidData and the actual length in the message.
Solutions
- Ensure the producer always writes exactly 16 bytes (e.g. uuid::Uuid::as_bytes()) for boundary ids
- Check for schema/version drift where id size changed between producer and consumer
- Validate the byte length before calling try_into and surface a clearer upstream error
- Regenerate/repair affected event records with correctly sized ids
Example fix
// before let id = boundary_id_from_slice(&bytes)?; // bytes.len() == 32 // after let uuid = uuid::Uuid::new_v4(); let id = boundary_id_from_slice(uuid.as_bytes())?; // always 16 bytes
Defensive patterns
Strategy: validation
Validate before calling
fn is_boundary_id(bytes: &[u8]) -> bool { bytes.len() == 16 } Type guard
fn as_boundary_id(bytes: &[u8]) -> Option<[u8; 16]> { bytes.try_into().ok() } Try / catch
match boundary_id_from_slice(&bytes) {
Ok(id) => id,
Err(e) if e.kind() == io::ErrorKind::InvalidData => { log::warn!("bad boundary id length: {e}"); skip_record(); },
Err(e) => return Err(e),
} Prevention
- Generate ids with a 16-byte source (uuid::Uuid) only
- Type-sign byte fields in proto comments/docs as 16-byte UUIDs
- Validate id length at the deserialization boundary before conversion
When it happens
Trigger: Converting a Vec<u8>/byte slice from protobuf bytes fields into BoundaryId where the producer wrote a truncated, zero-length, or otherwise non-16-byte buffer.
Common situations: Older producer versions writing 8- or 32-byte ids; empty bytes field defaulting to empty vec in proto3; manual id generation not using 16-byte UUIDs.
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
- {0}
- baml.json.deserialize failed
- blob size does not fit usize
- body record omitted log metadata
- CannotUnpack
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/22514955278bc0f6.
Report an issue: GitHub.
Appendix: source
Thrown at baml_language/crates/bex_events/src/value/record.rs:567
helper: helper.clone(),
}),
RunTarget::Companion {
parent_boundary_id,
function_name,
} => Target::Companion(crate::value::pb::CompanionRunTargetV1 {
parent_boundary_id: parent_boundary_id.map(|id| id.as_bytes().to_vec()),
function_name: function_name.clone(),
}),
RunTarget::Internal { name } => {
Target::Internal(crate::value::pb::InternalRunTargetV1 { name: name.clone() })
}
}),
}
}
fn boundary_id_from_slice(value: &[u8]) -> io::Result<BoundaryId> {
let bytes: [u8; 16] = value.try_into().map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("boundary id must be 16 bytes, got {}", value.len()),
)
})?;
Ok(BoundaryId::from_bytes(bytes))
}
fn run_status_to_proto(status: RunStatus) -> crate::value::pb::RunStatus {
match status {
RunStatus::Pending => crate::value::pb::RunStatus::Pending,
RunStatus::Running => crate::value::pb::RunStatus::Running,
RunStatus::WaitingForInput => crate::value::pb::RunStatus::WaitingForInput,
RunStatus::WaitingForEnv => crate::value::pb::RunStatus::WaitingForEnv,
RunStatus::Cancelling => crate::value::pb::RunStatus::Cancelling,
RunStatus::Succeeded => crate::value::pb::RunStatus::Succeeded,
RunStatus::Failed => crate::value::pb::RunStatus::Failed,
RunStatus::Cancelled => crate::value::pb::RunStatus::Cancelled,
RunStatus::Panicked => crate::value::pb::RunStatus::Panicked,View on GitHub (pinned to bd85ce9dee)