{"record":{"id":"a45b19e818b65f0f","repo":"BoundaryML/baml","slug":"body-record-omitted-log-metadata","errorCode":null,"errorMessage":"body record omitted log metadata","messagePattern":"body record omitted log metadata","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_events/src/value/read.rs","lineNumber":103,"sourceCode":"            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"value record mixed capture loss metadata with body metadata\",\n            ));\n        }\n        return Ok(ValueFileRecord::CaptureLoss(loss.try_into()?));\n    }\n    let metadata = record.metadata.ok_or_else(|| {\n        io::Error::new(io::ErrorKind::InvalidData, \"value record omitted metadata\")\n    })?;\n    if let Some(log_event) = record.log_event {\n        return Ok(ValueFileRecord::LogEvent(LogRecord {\n            value_ref: metadata.try_into()?,\n            body: record.body,\n            blob_ref: record.blob.map(TryInto::try_into).transpose()?,\n            event: log_event.try_into()?,\n        }));\n    }\n    Err(io::Error::new(\n        io::ErrorKind::InvalidData,\n        \"body record omitted log metadata\",\n    ))\n}\n\n#[cfg(test)]\nmod tests {\n    use prost::Message as _;\n\n    use crate::{\n        ids::BoundaryId,\n        value::{\n            LogEventRecord, LogRecord, ValueCodec, ValueRef,\n            encode::{encode_header, encode_log_event},\n            pb,\n        },\n    };\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_events/src/value/read.rs#L85-L121","documentation":"When decoding a bex_events event stream, a body record (an event body) arrived without the required log metadata (value_ref/event envelope fields). file_record_from_proto only produces a FileRecord when a preceding metadata record established the log context; otherwise it returns InvalidData. This protects the reader from assembling bodies that cannot be attributed to any log event.","triggerScenarios":"Calling read_bamlvalue_from_bytes on a stream where a body record appears before its corresponding ValueMetadataV1 record, or where the metadata record was dropped/truncated/corrupted by the writer.","commonSituations":"Truncated or partially-written trace files (process crash mid-write), hand-edited or externally-trimmed event logs, or a writer-version that emits records in an order this reader version does not expect.","solutions":["Regenerate or re-export the trace file from a healthy source; the file is missing its metadata record and cannot be repaired by the reader","Verify the producer and consumer bex_events versions match — a newer writer may order records differently","Check that the file was not truncated in transfer (compare sizes/checksums with the origin)","If reading a partial stream, skip to the next complete metadata+body pair instead of the orphaned body"],"exampleFix":"// before\nlet record = read_bamlvalue_from_bytes(&buf)?; // panics pipeline on orphaned body\n// after\nmatch read_bamlvalue_from_bytes(&buf) {\n    Ok(record) => emit(record),\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => skip_corrupt_chunk(),\n    Err(e) => return Err(e),\n}","handlingStrategy":"validation","validationCode":"fn has_log_metadata(record: &RawRecord) -> bool { record.metadata.is_some() }","typeGuard":"fn is_valid_body_record(r: &FileRecord) -> bool { r.event.is_some() && r.value_ref.is_some() }","tryCatchPattern":"match read_bamlvalue_from_bytes(&buf) { Ok(r) => Some(r), Err(e) if e.kind() == io::ErrorKind::InvalidData => { log::warn!(\"skipping orphaned body record: {e}\"); None }, Err(e) => return Err(e) }","preventionTips":["Never truncate event files mid-stream; use atomic writes or checksums","Keep writer and reader bex_events versions aligned","Validate record ordering (metadata before body) in your producer tests"],"tags":["rust","protobuf","deserialization","corrupt-data"],"backgroundTag":"unexpected-response-shape","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}