BoundaryML/baml · error · CtypesError

Invalid bigint hex string ({len} bytes)

Error message

Invalid bigint hex string ({len} bytes)

What it means

CtypesError::InvalidBigint { len } signals a bigint value decoded over the bridge was not a valid hex string. Per the source comment, the error deliberately carries only the input's byte length — not the payload — because untrusted hex blobs can reach the ~67M-char FFI cap and embedding them would bloat logs and leak payload contents.

Source

Thrown at baml_language/crates/bridge_ctypes/src/error.rs:23

/// 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,

    #[error("Union selected type `{selected}` is not a member of declared union `{union}`")]
    UnionSelectedTypeNotMember { selected: String, union: String },

    #[error("Internal error: {0}")]
    InternalError(String),
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Hex-encode bigints as clean hex text (no 0x prefix, even number of hex digits) before the FFI call.
  2. Validate hex in the host: check every char is [0-9a-fA-F] and len % 2 == 0, and log the length (the error only reports len).
  3. Trim whitespace/control characters from the payload before encoding.
  4. Check for encoding bugs (e.g. accidentally sending base64 or raw bytes).

Example fix

// before
payload = str(value).encode()  # "12345" decimal, not hex -> InvalidBigint
// after
payload = format("{:x}", value).encode()  # proper hex
assert len(payload) % 2 == 0 and all(c in b"0123456789abcdef" for c in payload)
Defensive patterns

Strategy: validation

Validate before calling

import re
HEX_RE = re.compile(r"^[0-9a-fA-F]+$")
def ensure_hex_bigint(b: bytes):
    if not b or len(b) % 2 != 0 or not HEX_RE.match(b.decode("ascii", "strict")):
        raise ValueError("bigint payload must be even-length hex")

Try / catch

try:
    send_inbound_bigint(payload)
except BridgeError as e:
    if "Invalid bigint hex string" in str(e):
        raise ValueError(f"bad hex bigint (len={len(payload)}); check encoding") from e
    raise

Prevention

When it happens

Trigger: Passing an InboundValue for a bigint/integer field whose bytes are not valid hex (e.g. non-hex characters, odd length, empty, or raw binary instead of hex-encoded text).

Common situations: Host code sending raw integer bytes instead of hex text; lower/uppercase or 0x-prefix mismatches the decoder doesn't accept; corrupted payloads truncated mid-hex-digit; user-supplied numbers passed through unvalidated.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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