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
- Clamp or validate the field value against bex_vm_types::Value::INT_MIN/INT_MAX before constructing the struct.
- Store the value as a BAML bigint (try_alloc_bigint) if it genuinely needs more than i63.
- 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
- Remember BAML `int` is 63-bit, not full i64.
- Range-check values crossing the Rust->VM boundary.
- Use bigint fields for values that can exceed i63.
- Cover interop code with range assertions in tests.
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
- failed to allocate bigint field `{field_name}`: {p}
- ntypeargs fits u16
- generic arity fits u32
- class field count fits u32
- Field access on non-class type
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/59d112d98d13a40f.
Report an issue: GitHub.