BoundaryML/baml · error

Value::Int payload is outside the i63 range [ , ]…

Error message

Value::Int payload {i} is outside the i63 range [{}, {}]; pre-tagged-pointer payloads with |value| >= 2^62 cannot be loaded

What it means

During deserialization, a ValueWire::Int payload is converted back to Value::Int via Value::try_int, which only accepts values fitting the i63 range ([-2^62, 2^62-1]) used by the tagged-pointer representation. Older wire payloads (pre-tagged-pointer) may contain full i64 integers whose magnitude reaches 2^62 or beyond; these cannot be represented as a tagged Value and are rejected with InvalidData instead of silently wrapping.

Solutions

  1. Regenerate the serialized data with the current runtime version so Int payloads fit the i63 range.
  2. Clamp or remap out-of-range integers before serialization on the producer side, or store them as BigInt/BigIntWire when |value| >= 2^62.
  3. Upgrade/downgrade so producer and consumer use the same tagged-pointer representation version.
  4. If exact huge values must survive, extend ValueWire with a wide-int variant and migrate the writer to emit it.

Example fix

// before
ValueWire::Int(big_i64_value) // written by old runtime, |v| >= 2^62
// after (producer)
let wire = if big_i64_value.unsigned_abs() >= 1u64 << 62 {
    ValueWire::BigInt(big_i64_value.into())
} else {
    ValueWire::Int(big_i64_value)
};
Defensive patterns

Strategy: validation

Validate before calling

// producer-side check before serializing an Int payload
fn fits_i63(v: i64) -> bool {
    v >= Value::INT_MIN && v <= Value::INT_MAX
}

Try / catch

// Rust consumer
let value = Value::deserialize_reader(&mut reader)
    .map_err(|e| if e.kind() == std::io::ErrorKind::InvalidData {
        MyError::LegacyIntPayload(e.to_string())
    } else {
        MyError::Io(e)
    })?;

Prevention

When it happens

Trigger: Deserializing (deserialize_reader / from-bytes style entry points in bex_vm_types Value) a wire blob produced by an older BAML runtime whose Int payloads were full i64, where any payload has |value| >= 2^62 (i.e. <= Value::INT_MIN or >= Value::INT_MAX out of range).

Common situations: Loading persisted VM state, caches, or IPC messages written by an older bex_vm_types version into a newer tagged-pointer runtime; cross-version compatibility between a producer binary and a consumer binary; test fixtures with extreme sentinel-like i64 constants (i64::MIN/MAX).

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at baml_language/crates/bex_vm_types/src/types/value.rs:538

        let proxy = match self.kind() {
            ValueKind::Null => ValueWire::Null,
            ValueKind::OmittedArg => ValueWire::OmittedArg,
            ValueKind::Int(i) => ValueWire::Int(i),
            ValueKind::Bool(b) => ValueWire::Bool(b),
            ValueKind::Object(ptr) => ValueWire::Object(ptr),
        };
        proxy.serialize(writer)
    }
}

impl BorshDeserialize for Value {
    fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
        let proxy = ValueWire::deserialize_reader(reader)?;
        Ok(match proxy {
            ValueWire::Null => Value::NULL,
            ValueWire::OmittedArg => Value::OMITTED_ARG,
            ValueWire::Int(i) => Value::try_int(i).ok_or_else(|| {
                std::io::Error::new(
                    std::io::ErrorKind::InvalidData,
                    format!(
                        "Value::Int payload {i} is outside the i63 range [{}, {}]; \
                         pre-tagged-pointer payloads with |value| >= 2^62 cannot be loaded",
                        Value::INT_MIN,
                        Value::INT_MAX,
                    ),
                )
            })?,
            ValueWire::Bool(b) => Value::bool(b),
            ValueWire::Object(ptr) => Value::object(ptr),
        })
    }
}

View on GitHub (pinned to bd85ce9dee)