BoundaryML/baml · error

int.ilog: invariants self > 0 && base >= 2 already enforced

Error message

int.ilog: invariants self > 0 && base >= 2 already enforced

What it means

Internal invariant panic in `int.ilog`. The function first validates `int > 0` and `base >= 2`, returning `VmBamlError::InvalidArgument` otherwise (that user-facing path is error 401's sibling). Because both invariants are enforced before the call, `checked_ilog` cannot return None, so the `unreachable!` only fires if that pre-validation was bypassed — a VM bug, not a user-facing condition.

Solutions

  1. If you actually passed self <= 0 or base < 2, you should be seeing InvalidArgument, not this panic — verify you are on an unmodified bex_vm build.
  2. Rebuild/upgrade bex_vm; this is an internal invariant failure in the ilog implementation.
  3. Report the exact (int, base) inputs to the baml_language maintainers.
Defensive patterns

Strategy: validation

Validate before calling

fn valid_ilog_args(int: i64, base: i64) -> bool {
    int > 0 && base >= 2
}

Try / catch

// Guard in BAML/Rust before calling ilog; the panic path is unreachable for valid input.
if !(int > 0 && base >= 2) { return Err(/* InvalidArgument */); }

Prevention

When it happens

Trigger: Calling `int.ilog(base)` on a BAML int with self <= 0 or base < 2 produces the normal InvalidArgument error, not this panic; this panic occurs only if the validation code path is skipped or checked_ilog returns None despite valid inputs (should be impossible).

Common situations: Seen only when hacking on the VM's native int package, or if a patched build altered the guard conditions above the checked_ilog call. BAML developers calling ilog with 0/negative values or base 1 get the regular 'base must be >= 2' error instead.

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

Appendix: source

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

            .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")
        })))
    }

    // ── Bit operations ────────────────────────────────────────────────────────

    fn leading_zeros(int: i64) -> i64 {
        i64::from(int.leading_zeros())
    }

    fn leading_ones(int: i64) -> i64 {
        i64::from(int.leading_ones())
    }

    fn trailing_zeros(int: i64) -> i64 {
        i64::from(int.trailing_zeros())
    }

    fn trailing_ones(int: i64) -> i64 {

View on GitHub (pinned to bd85ce9dee)