{"record":{"id":"a419928d0139fdb0","repo":"BoundaryML/baml","slug":"fn-name-expected-int-at-index-index","errorCode":null,"errorMessage":"{fn_name}: expected int at index {index}","messagePattern":"(.+?): expected int at index (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm/src/package_baml/root.rs","lineNumber":957,"sourceCode":"            value_type_name(vm, value)\n        );\n    };\n    match vm.get_object(ptr) {\n        Object::Float(float) => *float,\n        _ => unreachable!(\n            \"{fn_name}: expected float at index {index}, got {}\",\n            value_type_name(vm, value)\n        ),\n    }\n}\n\n/// Extracts an `i64` from a validated `int[]` element. Ints are unboxed tagged\n/// values, so no heap read is needed; a missing int tag is an upstream invariant\n/// violation.\nfn expect_int(value: Value, fn_name: &str, index: usize) -> i64 {\n    value\n        .as_int()\n        .unwrap_or_else(|| unreachable!(\"{fn_name}: expected int at index {index}\"))\n}\n\n#[cfg(test)]\nmod trunc_to_int_tests {\n    use super::{BamlPackageBaml, PackageBamlImpl};\n\n    /// `_trunc_to_int` must preserve the old `baml.math.trunc` semantics exactly:\n    /// truncate toward zero, saturate to the `i64` range, map NaN to `0`, and\n    /// never throw.\n    #[test]\n    fn trunc_to_int_saturating_semantics() {\n        assert_eq!(PackageBamlImpl::_trunc_to_int(3.7), 3);\n        assert_eq!(PackageBamlImpl::_trunc_to_int(-3.7), -3);\n        assert_eq!(PackageBamlImpl::_trunc_to_int(3.0), 3);\n        assert_eq!(PackageBamlImpl::_trunc_to_int(0.0), 0);\n        assert_eq!(PackageBamlImpl::_trunc_to_int(-0.0), 0);\n        // NaN maps to 0; ±∞ saturate to the i64 bounds (Rust's `as` cast).\n        assert_eq!(PackageBamlImpl::_trunc_to_int(f64::NAN), 0);","sourceCodeStart":939,"sourceCodeEnd":975,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm/src/package_baml/root.rs#L939-L975","documentation":"Panic in expect_int when an element of a validated int[] lacks the int tag. Ints are unboxed tagged values, so if as_int() returns None the upstream validation invariant was violated — the array is not actually all-ints.","triggerScenarios":"Calling sum (or other int-array natives) on an int[] whose contents include a non-int value at extraction time.","commonSituations":"Arrays assembled through unchecked/dynamic paths; type-checker gaps; mutation of the array after validation.","solutions":["Rebuild the array with only int elements before calling sum.","Verify the declared type of the array matches actual contents.","Report to maintainers — validated int[] should never contain non-ints."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before sum\nif (!arr.every(v => Number.isInteger(v))) throw new Error('expected int[] elements');","typeGuard":"const isIntArray = (a) => Array.isArray(a) && a.every(v => Number.isInteger(v));","tryCatchPattern":null,"preventionTips":["Validate array contents at construction time.","Keep declared int[] types accurate."],"tags":["vm-panic","invariant","int","type-safety"],"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-23T08:17:48.524Z"}