BoundaryML/baml · error
value metadata omitted availability
Error message
value metadata omitted availability
What it means
ValueMetadataV1.protobuf carried availability == Unspecified, i.e. the writer did not record whether the value payload is Pending/Available/Missing/Omitted/Lost. The TryFrom conversion for the internal record requires an explicit availability to correctly interpret payload presence, so Unspecified yields io::ErrorKind::InvalidData.
Source
Thrown at baml_language/crates/bex_events/src/value/record.rs:168
fn try_from(metadata: crate::value::pb::ValueMetadataV1) -> Result<Self, Self::Error> {
let codec = match metadata.codec() {
crate::value::pb::ValueCodec::BamlOutboundValue => ValueCodec::BamlOutboundValue,
crate::value::pb::ValueCodec::Unspecified => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"value metadata omitted codec",
));
}
};
let availability = match metadata.availability() {
crate::value::pb::ValueAvailability::Pending => ValueAvailability::Pending,
crate::value::pb::ValueAvailability::Available => ValueAvailability::Available,
crate::value::pb::ValueAvailability::Missing => ValueAvailability::Missing,
crate::value::pb::ValueAvailability::Omitted => ValueAvailability::Omitted,
crate::value::pb::ValueAvailability::Lost => ValueAvailability::Lost,
crate::value::pb::ValueAvailability::Unspecified => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"value metadata omitted availability",
));
}
};
Ok(Self {
id: metadata.id,
codec,
availability,
original_size_bytes: metadata
.original_size_bytes
.map(usize::try_from)
.transpose()
.map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
"original size does not fit usize",
)View on GitHub (pinned to bd85ce9dee)
Solutions
- Fix the producer to always set an explicit availability before serializing
- When constructing pb::ValueMetadataV1 manually, set availability (e.g. Available) explicitly
- Apply a backward-compat default (map Unspecified to Missing/Available per your data contract) at decode time
- Check writer/consumer version skew and add a migration step for legacy streams
Example fix
// before
let md = pb::ValueMetadataV1 { codec: ..., ..Default::default() };
// after
let md = pb::ValueMetadataV1 { codec: ..., availability: pb::ValueAvailability::Available as i32, ..Default::default() }; Defensive patterns
Strategy: validation
Validate before calling
if md.availability() == pb::ValueAvailability::Unspecified { return Err("availability unset"); } Type guard
fn has_availability(md: &pb::ValueMetadataV1) -> bool { md.availability() != pb::ValueAvailability::Unspecified } Try / catch
ValueRecord::try_from(md).map_err(|e| if e.to_string().contains("availability") { supply_default_availability(md) } else { e }) Prevention
- Set availability explicitly on every ValueMetadataV1
- Test that enum fields survive proto rebuilds/copies
- Document required enum fields in the schema contract
When it happens
Trigger: Decoding a ValueMetadataV1 where the availability field was never set by the producer, or was reset when the message was rebuilt/copied by intermediate code.
Common situations: Older writers predating the availability field, hand-built protos in tests/tools missing the setter, or schema migrations that defaulted new 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
- capture loss omitted kind
- capture loss omitted reason
- 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/fc651d36ae9146d1.
Report an issue: GitHub.