BoundaryML/baml · critical

`{field_name}: int` is outside BAML int range [{}, {}], got

Error message

`{field_name}: int` is outside BAML int range [{}, {}], got {}

What it means

Generated struct-copy code panics when a native i64 field value falls outside BAML's i63 int range (Value::INT_MIN..INT_MAX). Because `to_value` has no error channel, the generated code uses `Value::try_int(...).unwrap_or_else(|| panic!(...))` so the violation fails loudly in both debug and release rather than being silently truncated. This indicates a caller-side Rust bug that constructed an out-of-contract field value.

Source

Thrown at baml_language/crates/baml_builtins2_codegen/src/codegen.rs:641

        | BamlType::Generic(_)
        | BamlType::Named(_)
        | BamlType::Media(_) => "bex_vm_types::Value".to_string(),
    }
}

/// Generate the expression to convert a copy struct field to a Value.
fn copy_field_to_value(field_name: &str, ty: &BamlType) -> String {
    match ty {
        BamlType::RustType => {
            format!("bex_vm_types::Value::object(vm.alloc_rust_data(self.{field_name}))")
        }
        // `to_value` has no error channel (`fn to_value(self, vm) -> Value`),
        // so an out-of-i63 native i64 reaches this path only when caller-side
        // Rust constructed a struct field that violates the i63 BAML
        // contract. Fail loudly in *both* debug and release rather than
        // truncating silently via `Value::int`'s `debug_assert`.
        BamlType::Int => format!(
            "bex_vm_types::Value::try_int(self.{field_name}).unwrap_or_else(|| panic!(\
                \"`{field_name}: int` is outside BAML int range [{{}}, {{}}], got {{}}\", \
                bex_vm_types::Value::INT_MIN, bex_vm_types::Value::INT_MAX, self.{field_name}))"
        ),
        // Bigints are always heap-allocated, and allocation is fallible (the
        // value may exceed `MAX_BIGINT_BITS`). `to_value` has no error channel,
        // so — like the `int` range case above — fail loudly rather than
        // silently dropping the overflow. The panic reports the bit count from
        // `VmPanic::AllocFailure` (`{p}`), never the bigint itself, which could
        // be millions of digits long.
        BamlType::Bigint => format!(
            "vm.try_alloc_bigint(self.{field_name}).unwrap_or_else(|p| panic!(\
                \"failed to allocate bigint field `{field_name}`: {{p}}\"))"
        ),
        BamlType::Float => {
            format!("bex_vm_types::Value::object(vm.alloc_float(self.{field_name}))")
        }
        BamlType::Bool => format!("bex_vm_types::Value::bool(self.{field_name})"),
        BamlType::Null => "bex_vm_types::Value::NULL".to_string(),

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Clamp or validate the field value against bex_vm_types::Value::INT_MIN/INT_MAX before constructing the struct.
  2. Store the value as a BAML bigint (try_alloc_bigint) if it genuinely needs more than i63.
  3. Fix the producing code so the field stays within the i63 contract.

Example fix

// before
MyStruct { counter: huge_i64 }
// after
assert!(huge_i64 >= bex_vm_types::Value::INT_MIN && huge_i64 <= bex_vm_types::Value::INT_MAX);
MyStruct { counter: huge_i64 }
Defensive patterns

Strategy: validation

Validate before calling

fn fits_baml_int(v: i64) -> bool {
    v >= bex_vm_types::Value::INT_MIN && v <= bex_vm_types::Value::INT_MAX
}

Try / catch

// This is a panic, not a Result; validate before constructing
assert!(fits_baml_int(v), "field exceeds BAML i63 range: {v}");

Prevention

When it happens

Trigger: emit_copy_struct -> copy_field_to_value generating code for a `field_name: int` struct field whose runtime i64 value exceeds Value::INT_MAX or is below Value::INT_MIN; calling to_value on a struct built by hand in Rust with such a value.

Common situations: Interop code computing large i64 values (timestamps in nanos, hash values, counters) and passing them directly into BAML struct fields; misunderstanding that BAML `int` is 63-bit, not full i64.

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/59d112d98d13a40f. Report an issue: GitHub.