{"record":{"id":"e9d3559ff92091e4","repo":"BoundaryML/baml","slug":"int-random-in-range-offset-is-below-upper-lower","errorCode":null,"errorMessage":"int._random_in_range: offset is below upper - lower","messagePattern":"int\\._random_in_range: offset is below upper - lower","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm/src/package_baml/int.rs","lineNumber":112,"sourceCode":"            .into());\n        }\n        Ok(v)\n    }\n\n    fn _random_in_range(draw: i64, lower: i64, upper: i64) -> i64 {\n        if lower >= upper {\n            return upper;\n        }\n        let range = (i128::from(upper) - i128::from(lower)).cast_unsigned();\n        let u = (i128::from(draw) - i128::from(Value::INT_MIN)).cast_unsigned();\n\n        // Reject the remainder above the largest multiple of `range`.\n        let zone = INT_DOMAIN_SPAN / range * range;\n        if u >= zone {\n            return upper;\n        }\n        i64::try_from(i128::from(lower) + (u % range).cast_signed())\n            .unwrap_or_else(|_| unreachable!(\"int._random_in_range: offset is below upper - lower\"))\n    }\n\n    fn ilog(int: i64, base: i64) -> Result<i64, VmRustFnError> {\n        if int <= 0 {\n            return Err(VmBamlError::InvalidArgument {\n                message: format!(\"int.ilog: undefined for non-positive input (self = {int})\"),\n            }\n            .into());\n        }\n        if base < 2 {\n            return Err(VmBamlError::InvalidArgument {\n                message: format!(\"int.ilog: base must be >= 2, got {base}\"),\n            }\n            .into());\n        }\n        // Both invariants hold above, so checked_ilog cannot return None.\n        Ok(i64::from(int.checked_ilog(base).unwrap_or_else(|| {\n            unreachable!(\"int.ilog: invariants self > 0 && base >= 2 already enforced\")","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm/src/package_baml/int.rs#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Upgrade or rebuild the bex_vm crate — this indicates a bug in the rejection-sampling bounds math in int.rs.","Check that the lower/upper arguments passed to _random_in_range satisfy lower <= upper and (upper - lower) < i64::MAX.","File a bug with the failing (lower, upper) inputs against baml_language/crates/bex_vm."],"exampleFix":"// before (bug surface)\nlet zone = INT_DOMAIN_SPAN / range * range;\nif u >= zone { return upper; }\ni64::try_from(i128::from(lower) + (u % range).cast_signed())\n    .unwrap_or_else(|_| unreachable!(\"int._random_in_range: offset is below upper - lower\"))\n// after (defensive)\nlet zone = INT_DOMAIN_SPAN / range * range;\nif u >= zone { return upper; }\ni64::try_from(i128::from(lower) + (u % range).cast_signed())\n    .unwrap_or_else(|_| upper) // clamp instead of panicking","handlingStrategy":"validation","validationCode":"fn valid_random_range(lower: i64, upper: i64) -> bool {\n    lower <= upper && (i128::from(upper) - i128::from(lower)) < i64::MAX as i128\n}","typeGuard":null,"tryCatchPattern":"// Rust panic — cannot be caught in-process; validate inputs before invoking the VM API.\nassert!(valid_random_range(lower, upper));","preventionTips":["Only reach _random_in_range through the public BAML random APIs with lower <= upper.","Keep ranges well below the i64 domain span in generated BAML code.","Treat any occurrence as a VM bug and file it with the exact inputs."],"tags":["rust","internal-invariant","random","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}