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
- Clamp the shift amount before shifting: use a max(0, n) expression or an if-guard.
- Validate the shift operand is >= 0 before evaluating the expression.
- 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
- Clamp computed shift indices with a max(0, n) guard
- Add range assertions where shift amounts are derived from input data
- Prefer explicit if/else over arithmetic that can go negative
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
- shift << requires integer operands at
- array assignment index out of bounds
- array assignment on non-list value at
- array assignment requires a non-negative integer index at
- assign to undeclared variable
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)