BoundaryML/baml · error
capture loss omitted reason
Error message
capture loss omitted reason
What it means
CaptureLossV1.reason must be explicitly set (currently QueueFull) explaining why capture was lost; proto3's default Unspecified is rejected by the TryFrom conversion with InvalidData and this message. A loss record without a reason provides no actionable signal, so the reader treats it as malformed.
Source
Thrown at baml_language/crates/bex_events/src/value/record.rs:367
}
impl TryFrom<crate::value::pb::CaptureLossV1> for CaptureLossRecord {
type Error = io::Error;
fn try_from(value: crate::value::pb::CaptureLossV1) -> Result<Self, Self::Error> {
let kind = match value.kind() {
crate::value::pb::CaptureLossKind::Log => CaptureLossKind::Log,
crate::value::pb::CaptureLossKind::Unspecified => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"capture loss omitted kind",
));
}
};
let reason = match value.reason() {
crate::value::pb::CaptureLossReason::QueueFull => CaptureLossReason::QueueFull,
crate::value::pb::CaptureLossReason::Unspecified => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"capture loss omitted reason",
));
}
};
Ok(Self {
kind,
reason,
skipped_count: value.skipped_count,
call: value.call.map(TryInto::try_into).transpose()?,
message: value.message,
timestamp_ms: value.timestamp_ms,
})
}
}
impl From<&CaptureLossRecord> for crate::value::pb::CaptureLossV1 {
fn from(value: &CaptureLossRecord) -> Self {View on GitHub (pinned to bd85ce9dee)
Solutions
- Fix the producer to always set reason (e.g. CaptureLossReason::QueueFull) on loss records
- Set the enum explicitly when constructing the proto manually
- Apply a decode-time default (Unspecified -> QueueFull) if your contract only produces queue-full losses
- Align writer/reader versions and migrate legacy streams lacking the reason field
Example fix
// before
let loss = pb::CaptureLossV1 { kind: ..., ..Default::default() };
// after
let loss = pb::CaptureLossV1 { kind: ..., reason: pb::CaptureLossReason::QueueFull as i32, ..Default::default() }; Defensive patterns
Strategy: validation
Validate before calling
fn loss_reason_set(loss: &pb::CaptureLossV1) -> bool { loss.reason() != pb::CaptureLossReason::Unspecified } Type guard
fn valid_loss_reason(loss: &pb::CaptureLossV1) -> bool { matches!(loss.reason(), pb::CaptureLossReason::QueueFull) } Try / catch
CaptureLossRecord::try_from(loss).map_err(|e| if e.to_string().contains("omitted reason") { default_reason_record(loss) } else { e }) Prevention
- Set the reason enum explicitly whenever emitting a capture-loss record
- Add producer tests asserting loss records carry both kind and reason
- Keep writer/reader enum definitions in sync via a shared schema
When it happens
Trigger: Decoding a CaptureLossV1 whose reason field was left unset by the writer, or dropped when the message was rebuilt/copied by migration or proxy code.
Common situations: Older writers before the reason field existed, manually constructed loss records missing the enum setter, schema migrations defaulting new enum fields to Unspecified.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- value metadata omitted codec
- value metadata omitted availability
- capture loss omitted kind
- body record omitted log metadata
- original size does not fit usize
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/2bce733f99aa9636.
Report an issue: GitHub.