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

  1. Fix the producer to always set an explicit availability before serializing
  2. When constructing pb::ValueMetadataV1 manually, set availability (e.g. Available) explicitly
  3. Apply a backward-compat default (map Unspecified to Missing/Available per your data contract) at decode time
  4. 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

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


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/fc651d36ae9146d1. Report an issue: GitHub.