{"record":{"id":"7a93152f671b62e3","repo":"BoundaryML/baml","slug":"value-is-null-for-key-cffi-decode","errorCode":null,"errorMessage":"Value is null for key {}","messagePattern":"Value is null for key (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_cffi/src/ctypes/cffi_value_decode.rs","lineNumber":58,"sourceCode":"            HostVal::EnumValue(e) => Value::Enum(e.name, e.value, ()),\n            HostVal::Handle(handle) => {\n                let raw_ptr = RawPtrType::decode(handle)?;\n                Value::RawPtr(raw_ptr, ())\n            }\n        })\n    }\n}\n\npub(super) fn from_host_map_entry(\n    item: crate::baml::cffi::HostMapEntry,\n) -> Result<(String, Value), anyhow::Error> {\n    let key = match item.key {\n        Some(crate::baml::cffi::host_map_entry::Key::StringKey(k)) => k,\n        _ => return Err(anyhow::anyhow!(\"Key must be a string\")),\n    };\n    let value = item\n        .value\n        .ok_or(anyhow::anyhow!(\"Value is null for key {}\", key))?;\n    Ok((key, Value::decode(value)?))\n}\n","sourceCodeStart":40,"sourceCodeEnd":61,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_cffi/src/ctypes/cffi_value_decode.rs#L40-L61","documentation":"Thrown by from_host_map_entry once the key is validated as a string, when the entry's `value` field is None. The (String, Value) tuple cannot be built without a value, so the decode fails and includes the key name in the message.","triggerScenarios":"A host map entry is constructed with StringKey set but value left unset — e.g. a kwarg present in the dict with no encoded value, or a serializer skipping None-valued fields in the protobuf message.","commonSituations":"Passing None values in dictionaries across the CFFI, version-skewed bindings that omit value serialization for empty/null values, or partially built HostMapEntry objects in tests.","solutions":["Always set the value field on host map entries; encode nulls explicitly as a null Value instead of omitting the field","Upgrade host bindings/runtime so null values serialize correctly across the boundary","Filter or error on entries with missing values host-side before invoking the BAML client"],"exampleFix":"// before (Python)\nparams = {\"temperature\": None}\n\n// after\nparams = {\"temperature\": baml_null}  # explicit encoded null value","handlingStrategy":"validation","validationCode":"if any(v is _unset_sentinel for v in entry_map.values()):\n    raise ValueError(\"Every map entry must carry an encoded value; use an explicit null\")","typeGuard":"def all_entries_have_values(entries) -> bool:\n    return all(getattr(e, 'value', None) is not None for e in entries)","tryCatchPattern":"try:\n    result = client.CallFunction(fn, kwargs)\nexcept Exception as e:\n    if \"Value is null for key\" in str(e):\n        raise ValueError(\"Map entry value missing; encode nulls explicitly or drop the entry\") from e\n    raise","preventionTips":["Never leave the protobuf value field unset; use the bindings' null encoding","Filter out None-valued entries host-side before the call","Keep generated bindings and engine versions synchronized"],"tags":["ffi","decode","protobuf","rust"],"backgroundTag":"null-argument","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}