BoundaryML/baml · error

Key is missing

Error message

Key is missing

What it means

Thrown by from_host_kv_to_baml_kv when converting a host-language key/value pair into a BAML key/value pair and the protobuf HostMapEntry carries no key at all (the oneof `key` is None). The FFI boundary contract requires every map entry to have a key of a supported type, so a missing key is a malformed payload and the decode fails fast with anyhow::bail.

Source

Thrown at engine/language_client_cffi/src/ctypes/baml_value_decode.rs:58

                .into_iter()
                .map(|(k, v)| from_ffi_value_to_baml_value(v).map(|v| (k, v)))
                .collect::<Result<_, _>>()?,
        )),
        crate::ffi::Value::Enum(e, value, _) => Ok(BamlValue::Enum(e, value)),
    }
}

pub(super) fn from_host_kv_to_baml_kv(
    item: crate::baml::cffi::HostMapEntry,
) -> Result<(String, BamlValue), anyhow::Error> {
    use crate::baml::cffi::host_map_entry::Key;
    let key = match item.key {
        Some(Key::StringKey(key)) => key,
        Some(Key::EnumKey(key)) => key.value,
        Some(Key::IntKey(_)) | Some(Key::BoolKey(_)) => {
            anyhow::bail!("only string keys are supported")
        }
        None => anyhow::bail!("Key is missing"),
    };

    let value = item
        .value
        .ok_or(anyhow::anyhow!("Value is null for key {}", key))?;

    Ok((key, BamlValue::decode(value)?))
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Regenerate/upgrade the host-language BAML client bindings so they match the engine's cffi schema and always populate the key field
  2. Inspect the payload being passed across the boundary and ensure every map entry sets string_key (or enum_key) before calling the BAML function
  3. Check whether an intermediate serializer is dropping keys (e.g. null keys in a dict) and filter or reject such entries host-side before the call

Example fix

// before (host side, Python)
kwargs = {None: "v"}
client.CallFunction(fn_name, kwargs)

// after
kwargs = {"my_param": "v"}
client.CallFunction(fn_name, kwargs)
Defensive patterns

Strategy: validation

Validate before calling

# host side, before calling BAML
bad = [k for k in entries if k is None or not isinstance(k, str)]
if bad:
    raise ValueError(f"Map entries with missing/non-string keys: {bad}")

Type guard

def has_valid_keys(entries: dict) -> bool:
    return all(isinstance(k, str) for k in entries)

Try / catch

try:
    result = client.CallFunction(fn, kwargs)
except Exception as e:
    if "Key is missing" in str(e):
        raise ValueError("FFI map entry missing key; check bindings version and kwargs construction") from e
    raise

Prevention

When it happens

Trigger: A host caller (e.g. Python/Node via the CFFI) constructs or passes a map entry with key left unset when invoking BAML functions with kwargs/tags, or a protobuf HostMapEntry is built programmatically without setting the string_key/enum_key field.

Common situations: Version mismatch between the generated cffi bindings and the runtime (older host SDK omitting the key field), hand-constructed protobuf messages in tests, or serialization dropping null/empty keys before crossing the FFI boundary.

Related errors


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