BoundaryML/baml · error

validated int sort value should be int

Error message

validated int sort value should be int

What it means

Panic inside the native `sort` implementation for `int[]` when a comparator encounters an element that is not an int. The array was supposed to be validated as an int array before reaching the native path, so a non-int element means an upstream invariant was broken (e.g. the array contents changed after validation).

Solutions

  1. Verify the array is not mutated concurrently or aliased while being sorted.
  2. Re-check how the array was constructed; rebuild it with only int elements before sorting.
  3. Report to maintainers if inputs are statically int[] — this is an internal invariant break, not a user error.
Defensive patterns

Strategy: validation

Validate before calling

// before sort
if (!arr.every(v => typeof v === 'number' && Number.isInteger(v))) throw new Error('sort: array must contain only ints');

Type guard

const isIntArray = (a) => Array.isArray(a) && a.every(v => Number.isInteger(v));

Prevention

When it happens

Trigger: Calling sort on an `int[]` where an element's underlying tag is not an int at sort time — typically via mutation of the array between validation and sorting, or a VM bug bypassing element validation.

Common situations: Mutating a shared array (from another thread, alias, or callback) while sorting; type-checker gaps that let a mixed-type array be labeled int[]; VM bugs.

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

Appendix: source

Thrown at baml_language/crates/bex_vm/src/package_baml/root.rs:70

            };
            if values.len() <= 1 {
                return NativeCallResult::Done(*arr);
            }
            match validate_natural_order_with_vm(vm, "sort", &values) {
                Ok(domain) => domain,
                Err(e) => return NativeCallResult::Error(e),
            }
        };
        if matches!(domain, NaturalDomain::Int) {
            // Int values are tag-only (no heap reads), so the comparator
            // needs no `&BexVm` and the backing Vec sorts truly in place.
            let mut values = match vm.as_array_mut(arr) {
                Ok(guard) => guard,
                Err(e) => return NativeCallResult::Error(e.into()),
            };
            values.sort_by(|left, right| {
                left.as_int()
                    .expect("validated int sort value should be int")
                    .cmp(
                        &right
                            .as_int()
                            .expect("validated int sort value should be int"),
                    )
            });
            return NativeCallResult::Done(*arr);
        }
        // Heap-read domains (float/bigint/string): the comparator needs
        // `&BexVm`, which conflicts with holding the array's mutable guard —
        // sort a snapshot of the backing Vec, then swap it back in. One Vec
        // (re)allocation; still no per-element BAML round trips or re-push.
        let mut values = match vm.as_array(arr) {
            Ok(guard) => guard.to_vec(),
            Err(e) => return NativeCallResult::Error(e.into()),
        };
        values.sort_by(|left, right| compare_natural_values(vm, domain, *left, *right));
        match vm.as_array_mut(arr) {

View on GitHub (pinned to bd85ce9dee)