BoundaryML/baml · error
Value is null for key {}
Error message
Value is null for key {} What it means
Thrown by from_host_kv_to_baml_kv after the key has been resolved, when the HostMapEntry's `value` field is None. A key/value pair must carry both parts; a present key with a null value cannot be represented as a BamlValue, so the decode bails with the offending key name in the message.
Source
Thrown at engine/language_client_cffi/src/ctypes/baml_value_decode.rs:63
}
}
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
- Ensure every argument/tag entry has its value set before crossing the FFI boundary; represent nulls as an explicit BamlValue::Null rather than an unset field
- Upgrade the host SDK/bindings to match the engine version so optional-value serialization is consistent
- Validate the kwargs/tags map host-side and drop or fill entries with missing values before calling the BAML function
Example fix
// before (host side)
kwargs = {"model": None} // value field left unset
// after
kwargs = {"model": client.baml_options.null_value} // explicit null BamlValue Defensive patterns
Strategy: validation
Validate before calling
# host side
missing = [k for k, v in kwargs.items() if v is _unset_sentinel]
if missing:
raise ValueError(f"Arguments with no encoded value: {missing}") Type guard
def all_values_set(entries: dict) -> bool:
return all(v is not _unset_sentinel for v in entries.values()) Try / catch
try:
result = client.CallFunction(fn, kwargs)
except Exception as e:
if "Value is null for key" in str(e):
raise ValueError(f"Pass an explicit BAML null instead of an unset value for: {e}") from e
raise Prevention
- Encode null parameters as explicit BAML null values, not omitted fields
- Use the official client builder APIs rather than hand-building protobuf messages
- Pin matching versions of the generated bindings and runtime
When it happens
Trigger: A host caller passes a map entry whose value was not set (protobuf oneof/value absent), e.g. function arguments, tags, or kwargs where one parameter was declared but given no value.
Common situations: Passing None/null parameter values through the CFFI without wrapping them as an explicit BAML null, binding/runtime version skew, or builders that add keys before assigning values.
Related errors
- Key is missing
- Value is null for key {}
- Failed to decode BamlValue
- Protobuf decode error: {0}
- Key must be a string
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/60384b1e0be85206.
Report an issue: GitHub.