BoundaryML/baml · error · CtypesError
Map entry missing key
Error message
Map entry missing key
What it means
CtypesError::MapEntryMissingKey is raised during protobuf value decoding when a map entry arrives without its key field populated. The bridge requires both key and value in each map entry to reconstruct the map.
Source
Thrown at baml_language/crates/bridge_ctypes/src/error.rs:17
//! Error types used by the shared ctypes conversion logic.
use thiserror::Error;
/// Errors that can occur during value encoding/decoding for the bridge.
#[derive(Debug, Error)]
pub enum CtypesError {
#[error("Protobuf decode error: {0}")]
ProtobufDecode(#[from] prost::DecodeError),
#[error("Null buffer pointer")]
NullBuffer,
#[error("Invalid handle key: {0}")]
InvalidHandleKey(u64),
#[error("Map entry missing key")]
MapEntryMissingKey,
/// Carries only the input length, not the input itself — untrusted hex
/// blobs can be up to the FFI decode cap (~67M chars), and embedding
/// them in error messages bloats logs and exposes payload contents.
#[error("Invalid bigint hex string ({len} bytes)")]
InvalidBigint { len: usize },
/// Carries only the input length for over-cap decimal type literals, so a
/// hostile descriptor cannot amplify logs by echoing its full payload.
#[error("Invalid decimal bigint literal ({len} bytes)")]
InvalidBigintLiteral { len: usize },
#[error(
"Invalid InboundValue.value_type: a root union or optional does not identify one exact selected type"
)]
InvalidInboundValueTypeRootUnion,
View on GitHub (pinned to bd85ce9dee)
Solutions
- Regenerate/upgrade the producer so map entries always set the key field.
- Inspect the serialized bytes (decode independently) to find the entry missing its key.
- Fix producers that skip empty keys when assembling the map message.
- Validate payloads with a round-trip encode/decode before crossing the FFI boundary.
Example fix
// before
entries.push(MapEntry { value: Some(v), ..Default::default() }) // key omitted
// after
entries.push(MapEntry { key: k, value: Some(v), ..Default::default() }) Defensive patterns
Strategy: validation
Validate before calling
for entry in map_value.entries:
if not entry.HasField("key") or entry.key == "":
raise ValueError("map entry missing key before FFI decode") Try / catch
try:
val = bridge.decode_inbound(buf, len(buf))
except BridgeError as e:
if "Map entry missing key" in str(e):
raise ValueError("producer sent a map entry without a key; fix serializer") from e
raise Prevention
- Round-trip encode/decode maps in tests before sending over FFI
- Keep map serializers on the same generated-code version as the bridge
- Never drop empty keys when assembling map entries
When it happens
Trigger: Decoding an InboundValue containing a map whose entries have a value but no key — usually a hand-built protobuf message or a schema mismatch where the key field was omitted or serialized as empty.
Common situations: Manually constructed protobuf payloads in tests/tools; older SDK versions serializing maps differently than the bridge expects; a producer bug dropping empty-string keys.
Related errors
- Protobuf decode error: {0}
- Invalid InboundValue.value_type: a root union or optional do
- Failed to decode Value
- Union selected type `{selected}` is not a member of declared
- Key is missing
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/8b9b1fce8454db2d.
Report an issue: GitHub.