{"record":{"id":"f37002a7e948ccbb","repo":"BoundaryML/baml","slug":"protobuf-decode-error-0","errorCode":null,"errorMessage":"Protobuf decode error: {0}","messagePattern":"Protobuf decode error: (.+?)","errorType":"error_code","errorClass":"CtypesError","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bridge_ctypes/src/error.rs","lineNumber":8,"sourceCode":"//! Error types used by the shared ctypes conversion logic.\n\nuse thiserror::Error;\n\n/// Errors that can occur during value encoding/decoding for the bridge.\n#[derive(Debug, Error)]\npub enum CtypesError {\n    #[error(\"Protobuf decode error: {0}\")]\n    ProtobufDecode(#[from] prost::DecodeError),\n\n    #[error(\"Null buffer pointer\")]\n    NullBuffer,\n\n    #[error(\"Invalid handle key: {0}\")]\n    InvalidHandleKey(u64),\n\n    #[error(\"Map entry missing key\")]\n    MapEntryMissingKey,\n\n    /// Carries only the input length, not the input itself — untrusted hex\n    /// blobs can be up to the FFI decode cap (~67M chars), and embedding\n    /// them in error messages bloats logs and exposes payload contents.\n    #[error(\"Invalid bigint hex string ({len} bytes)\")]\n    InvalidBigint { len: usize },\n\n    /// Carries only the input length for over-cap decimal type literals, so a","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bridge_ctypes/src/error.rs#L1-L26","documentation":"CtypesError::ProtobufDecode wraps a prost::DecodeError raised while decoding a protobuf-encoded message crossing the bridge FFI boundary. It means the byte buffer handed to the ctypes conversion layer was not valid protobuf for the expected message type (corrupt, truncated, or produced by an incompatible schema).","triggerScenarios":"Calling bridge functions that accept encoded InboundValue/descriptor buffers when the bytes fail prost decoding — wrong message type, truncated buffer, mismatched protobuf schema versions between host and library.","commonSituations":"Version skew between a client SDK and the native bridge library (schema changed); buffers truncated to an FFI length cap; passing raw (non-protobuf) bytes; endianness/copy bugs in the caller's marshalling code.","solutions":["Ensure the caller encodes with the same protobuf schema version the bridge was built with; rebuild/realign both sides.","Verify the buffer length and contents before the call (decode the bytes independently with prost to see the underlying error).","Check that the full serialized message, not a truncated slice, is passed.","Regenerate the protobuf bindings if the schema was updated."],"exampleFix":"// before\nlet val = bridge::decode_inbound(&buf[..len-1])?; // truncated -> ProtobufDecode\n// after\nlet val = bridge::decode_inbound(&buf)?;","handlingStrategy":"validation","validationCode":"import google.protobuf\n# Independently decode before crossing the FFI boundary:\nmsg.ParseFromString(buf)  # raises DecodeError early with a clear cause\nassert msg.IsInitialized()","typeGuard":null,"tryCatchPattern":"try:\n    result = bridge.decode(buf, len(buf))\nexcept BridgeError as e:\n    if \"Protobuf decode error\" in str(e):\n        raise ValueError(f\"payload not valid protobuf (len={len(buf)})\") from e\n    raise","preventionTips":["Pin and regenerate protobuf bindings on both sides of the FFI when the schema changes","Always pass the full serialized buffer with its exact length","Unit-test the encode->decode round trip whenever you touch serialization"],"tags":["protobuf","ffi","decoding","rust"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}