BoundaryML/baml · error
trace call process id must be 16 bytes, got {}
Error message
trace call process id must be 16 bytes, got {} What it means
TraceCallKeyV1.process_id must be exactly 16 bytes (a 128-bit UUID-style identifier) to convert into the internal TraceCallKey's [u8; 16]. The TryFrom impl rejects any other length, including the length actually received, via InvalidData with this formatted message.
Source
Thrown at baml_language/crates/bex_events/src/value/record.rs:262
}
}
impl From<&BlobRef> for crate::value::pb::BlobRefV1 {
fn from(value: &BlobRef) -> Self {
Self {
algorithm: value.algorithm.clone(),
digest: value.digest.clone(),
size_bytes: u64::try_from(value.size_bytes).unwrap_or(u64::MAX),
}
}
}
impl TryFrom<crate::value::pb::TraceCallKeyV1> for TraceCallKey {
type Error = io::Error;
fn try_from(value: crate::value::pb::TraceCallKeyV1) -> Result<Self, Self::Error> {
let process_id: [u8; 16] = value.process_id.as_slice().try_into().map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
format!(
"trace call process id must be 16 bytes, got {}",
value.process_id.len()
),
)
})?;
Ok(Self {
process_euid: ProcessEuid(process_id),
engine_id: EngineId(value.engine_id),
thread_id: BexThreadId(value.thread_id),
call_id: BexCallId(value.call_id),
})
}
}
impl From<TraceCallKey> for crate::value::pb::TraceCallKeyV1 {
fn from(value: TraceCallKey) -> Self {View on GitHub (pinned to bd85ce9dee)
Solutions
- Fix the producer to always emit a 16-byte process_id (e.g. a UUID v4 as raw bytes)
- Pad/truncate or regenerate IDs in a migration tool when converting legacy streams
- Validate process_id.len() == 16 at the writer boundary before serializing
- Inspect the reported length in the message to identify which producer/version wrote the bad ID
Example fix
// before
let process_id = value.process_id; // arbitrary-length Vec<u8>
// after
let mut process_id = [0u8; 16];
if value.process_id.len() == 16 { process_id.copy_from_slice(&value.process_id); } else { return Err(...); } Defensive patterns
Strategy: validation
Validate before calling
fn is_uuid16(id: &[u8]) -> bool { id.len() == 16 } Type guard
fn as_process_id(bytes: &[u8]) -> Option<[u8; 16]> { bytes.try_into().ok() } Try / catch
TraceCallKey::try_from(raw).map_err(|e| { warn!("bad process id: {e}"); CorruptionKind::BadProcessId.into() }) Prevention
- Generate process IDs as 16-byte UUIDs at the producer
- Assert id length in producer unit tests
- Include a format/version byte scheme if ids may evolve
When it happens
Trigger: Decoding a TraceCallKeyV1 whose process_id field is empty, truncated by corruption, or written with a different-length ID (e.g. 8-byte, 32-byte hex string) by an incompatible producer.
Common situations: Version skew where an older/newer writer uses a different process-id representation, manual proto construction with placeholder IDs, or byte-level file corruption.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- body record omitted log metadata
- value metadata omitted codec
- value metadata omitted availability
- original size does not fit usize
- retained size does not fit usize
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/380a9d4400e5b51b.
Report an issue: GitHub.