BoundaryML/baml · error

negative shift amount at

Error message

negative shift amount at {:?}

What it means

BAML's left-shift operator rejects a negative shift amount. Even when both operands are integers, evaluate_binary_op checks `b < 0` before shifting and bails with this message, since a negative shift is undefined/unsafe.

Solutions

  1. Clamp the shift amount before shifting: use a max(0, n) expression or an if-guard.
  2. Validate the shift operand is >= 0 before evaluating the expression.
  3. If right-shifting was intended (reversing direction), use `>>` instead.

Example fix

// before (BAML)
let scaled = 1 << (index - offset);
// after
let n = if (index - offset < 0) { 0 } else { index - offset };
let scaled = 1 << n;
Defensive patterns

Strategy: validation

Validate before calling

// guard shift amount before <<
if (shift < 0) throw new Error('negative shift amount');

Type guard

const validShift = (n) => Number.isInteger(n) && n >= 0;

Try / catch

try {
  result = evaluate(expr);
} catch (e) {
  if (String(e).includes('negative shift amount')) {
    result = evaluate(clampShiftAmounts(expr));
  } else throw e;
}

Prevention

When it happens

Trigger: Evaluating `a << b` where `b` is a negative integer, e.g. `1 << -2`, or a shift amount computed from a subtraction that went negative (`1 << (i - 5)` when i < 5).

Common situations: Loop-computed shift indices that underflow below zero; signed offsets from config or LLM output that were assumed non-negative.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at engine/baml-compiler/src/thir/interpret.rs:2513

            }
            _ => bail!("bitwise & requires integer operands at {:?}", meta.0),
        },
        BinaryOperator::BitOr => match (left_val.clone(), right_val.clone()) {
            (BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Int(b, _)) => {
                BamlValueWithMeta::Int(a | b, meta.clone())
            }
            _ => bail!("bitwise | requires integer operands at {:?}", meta.0),
        },
        BinaryOperator::BitXor => match (left_val.clone(), right_val.clone()) {
            (BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Int(b, _)) => {
                BamlValueWithMeta::Int(a ^ b, meta.clone())
            }
            _ => bail!("bitwise ^ requires integer operands at {:?}", meta.0),
        },
        BinaryOperator::Shl => match (left_val.clone(), right_val.clone()) {
            (BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Int(b, _)) => {
                if b < 0 {
                    bail!("negative shift amount at {:?}", meta.0);
                }
                BamlValueWithMeta::Int(a << b, meta.clone())
            }
            _ => bail!("shift << requires integer operands at {:?}", meta.0),
        },
        BinaryOperator::Shr => match (left_val.clone(), right_val.clone()) {
            (BamlValueWithMeta::Int(a, _), BamlValueWithMeta::Int(b, _)) => {
                if b < 0 {
                    bail!("negative shift amount at {:?}", meta.0);
                }
                BamlValueWithMeta::Int(a >> b, meta.clone())
            }
            _ => bail!("shift >> requires integer operands at {:?}", meta.0),
        },
        BinaryOperator::InstanceOf => match (left_val.clone(), right_val.clone()) {
            (BamlValueWithMeta::Class(class, ..), BamlValueWithMeta::Class(right_class, ..)) => {
                BamlValueWithMeta::Bool(class == right_class, meta.clone())
            }

View on GitHub (pinned to bd85ce9dee)