BoundaryML/baml · error

Failed to decode Value

Error message

Failed to decode Value

What it means

Thrown while decoding BAML object constructor kwargs when an entry has a string key but its value field is None/absent in the protobuf message. The library requires every named argument to carry a decodable Value; an empty value cannot be mapped to a BAML value.

Source

Thrown at engine/language_client_cffi/src/ctypes/object_args_decode.rs:62

}

impl Decode for BamlObjectConstructorArgs {
    type From = crate::baml::cffi::BamlObjectConstructorInvocation;

    fn decode(from: Self::From) -> Result<Self, anyhow::Error> {
        Ok(BamlObjectConstructorArgs {
            object_type: BamlObjectType::try_from(from.r#type)?,
            kwargs: from
                .kwargs
                .into_iter()
                .map(|v| {
                    let key = match v.key {
                        Some(crate::baml::cffi::host_map_entry::Key::StringKey(k)) => k,
                        _ => return Err(anyhow::anyhow!("Key must be a string")),
                    };
                    match v.value {
                        Some(value) => Ok((key, Value::decode(value)?)),
                        None => Err(anyhow::anyhow!("Failed to decode Value")),
                    }
                })
                .collect::<Result<_, _>>()?,
        })
    }
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure all argument values are provided at the call site and none are silently dropped to None
  2. Reinstall/upgrade the BAML client package so client and native library versions match
  3. Check that no custom serialization layer strips value fields from map entries

Example fix

// before
args = {"name": "x", "optional": None}  # entry sent with unset value
// after
args = {"name": "x"}  # omit unset args entirely
Defensive patterns

Strategy: validation

Validate before calling

def validate_kwargs(kwargs):
    for k, v in kwargs.items():
        if v is None:
            raise ValueError(f"kwarg '{k}' has no value; omit it instead")

Type guard

def has_value(entry): return entry.value is not None

Try / catch

try:
    obj = CffiClass(**kwargs)
except Exception as e:
    if 'Failed to decode Value' in str(e):
        kwargs = {k: v for k, v in kwargs.items() if v is not None}
        obj = CffiClass(**kwargs)
    else:
        raise

Prevention

When it happens

Trigger: Passing an object constructor argument whose HostMapEntry contains Some(key) but no value variant in the oneof, typically from a mismatched client binding or a serialization bug.

Common situations: Version mismatch between the generated host-language client and the native CFFI binary, or host code that inserts placeholder entries with unset values into the kwargs map.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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