BoundaryML/baml · error

int._random_in_range: offset is below upper - lower

Error message

int._random_in_range: offset is below upper - lower

What it means

This is an internal invariant panic inside `int._random_in_range` in the Bex VM's BAML int package. The function computes `lower + (u % range)` where `u < zone` (the largest multiple of `range` below INT_DOMAIN_SPAN), so the mathematical result is guaranteed to be <= upper - lower and must always fit in i64. The `unwrap_or_else` only fires if the i128→i64 conversion fails, which would mean the rejection logic above is broken — i.e. a VM implementation bug, not user error.

Source

Thrown at baml_language/crates/bex_vm/src/package_baml/int.rs:112

            .into());
        }
        Ok(v)
    }

    fn _random_in_range(draw: i64, lower: i64, upper: i64) -> i64 {
        if lower >= upper {
            return upper;
        }
        let range = (i128::from(upper) - i128::from(lower)).cast_unsigned();
        let u = (i128::from(draw) - i128::from(Value::INT_MIN)).cast_unsigned();

        // Reject the remainder above the largest multiple of `range`.
        let zone = INT_DOMAIN_SPAN / range * range;
        if u >= zone {
            return upper;
        }
        i64::try_from(i128::from(lower) + (u % range).cast_signed())
            .unwrap_or_else(|_| unreachable!("int._random_in_range: offset is below upper - lower"))
    }

    fn ilog(int: i64, base: i64) -> Result<i64, VmRustFnError> {
        if int <= 0 {
            return Err(VmBamlError::InvalidArgument {
                message: format!("int.ilog: undefined for non-positive input (self = {int})"),
            }
            .into());
        }
        if base < 2 {
            return Err(VmBamlError::InvalidArgument {
                message: format!("int.ilog: base must be >= 2, got {base}"),
            }
            .into());
        }
        // Both invariants hold above, so checked_ilog cannot return None.
        Ok(i64::from(int.checked_ilog(base).unwrap_or_else(|| {
            unreachable!("int.ilog: invariants self > 0 && base >= 2 already enforced")

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Upgrade or rebuild the bex_vm crate — this indicates a bug in the rejection-sampling bounds math in int.rs.
  2. Check that the lower/upper arguments passed to _random_in_range satisfy lower <= upper and (upper - lower) < i64::MAX.
  3. File a bug with the failing (lower, upper) inputs against baml_language/crates/bex_vm.

Example fix

// before (bug surface)
let zone = INT_DOMAIN_SPAN / range * range;
if u >= zone { return upper; }
i64::try_from(i128::from(lower) + (u % range).cast_signed())
    .unwrap_or_else(|_| unreachable!("int._random_in_range: offset is below upper - lower"))
// after (defensive)
let zone = INT_DOMAIN_SPAN / range * range;
if u >= zone { return upper; }
i64::try_from(i128::from(lower) + (u % range).cast_signed())
    .unwrap_or_else(|_| upper) // clamp instead of panicking
Defensive patterns

Strategy: validation

Validate before calling

fn valid_random_range(lower: i64, upper: i64) -> bool {
    lower <= upper && (i128::from(upper) - i128::from(lower)) < i64::MAX as i128
}

Try / catch

// Rust panic — cannot be caught in-process; validate inputs before invoking the VM API.
assert!(valid_random_range(lower, upper));

Prevention

When it happens

Trigger: Calling `int._random_in_range` (via the BAML `random` int APIs) with a range so large that `INT_DOMAIN_SPAN / range * range` no longer correctly bounds `u`, or a lower/upper pair whose span exceeds i64. Direct calls are only possible from native VM glue code; normal BAML code cannot construct this state.

Common situations: Only encountered during Bex VM development, porting, or when running with a nonstandard/corrupted stdlib build where the int package's domain constants were changed. End users of BAML should never see this.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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