gleam-lang/gleam · error
Tried to reduce bit array size without 2 operands
Error message
Tried to reduce bit array size without 2 operands
What it means
This is an internal compiler panic in Gleam's parser, not a user-facing diagnostic. `reduce_bit_array_size` (compiler-core/src/parse.rs) collapses a binary expression that combines two bit-array size operands, and the match arm `_` should be unreachable. It fires when the parser hands the reducer something other than the two-operand expressions it expects, indicating a parser bug or an unhandled token/operator shape.
Solutions
- Reproduce with the offending snippet and file a bug at the gleam repository (compiler-core/src/parse.rs, reduce_bit_array_size) with the source that panicked.
- If you are a contributor: extend the match in `reduce_bit_array_size` to handle the new expression/operator variant instead of falling through to `_`.
- Upgrade Gleam to the latest version in case the panic was already fixed.
Example fix
// before
_ => panic!("Tried to reduce bit array size without 2 operands"),
// after
UntypedExpr::BitArraySizeConcat { .. } => { /* handle new variant */ }
_ => panic!("Tried to reduce bit array size without 2 operands"), Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
// Rust: match exhaustively before calling the reducer
match (&left, &operator, &right) {
(UntypedExpr::BitArraySizeInt { .. }, _, _) => {},
_ => panic/return Err("unsupported bit array size operand"),
} Try / catch
// Panics are not catchable in idiomatic Rust; fix the parser arms or use catch_unwind around parsing in tooling. std::panic::catch_unwind(|| parse(input))
Prevention
- Never call internal parse:: reduction functions directly; go through the public parser API.
- When adding a new bit-array size expression variant, update every match in reduce_bit_array_size.
- Run the parser fuzz target after token/AST changes.
When it happens
Trigger: Calling `reduce_bit_array_size` with a left/right AST node or operator that is not one of the handled variants — i.e. any fall-through `_` case in the match over expression/operator shapes while parsing a bit array size segment like `<<x:size(N-1)>>`.
Common situations: Developers hit this only when modifying the Gleam parser (adding a new operator or expression variant to bit-array sizes without extending the reducer), or when fuzzing/parsing malformed input that reaches an unhandled arm. End users of the gleam CLI (`gleam add`, etc.) never trigger it directly.
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
- Token could not be converted to binop.
- channel buffer write
- Expression not fully reduced.
- invalid constants can not be in an untyped ast
- Tried to reduce without 2 expressions
AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14).
Data as JSON: /api/errors/30b568ea2439d1e4.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-core/src/parse.rs:5177
/// Simple-Precedence-Parser, perform reduction for bit array size expressions
fn reduce_bit_array_size((_, token, _): Spanned, experession_stack: &mut Vec<BitArraySize<()>>) {
let operator = token_to_bit_array_size_operator(&token)
.expect("only operator tokens are pushed onto the bit array size opstack");
match (experession_stack.pop(), experession_stack.pop()) {
(Some(right), Some(left)) => {
let location = SrcSpan {
start: left.location().start,
end: right.location().end,
};
experession_stack.push(BitArraySize::BinaryOperator {
left: Box::new(left),
right: Box::new(right),
operator,
location,
});
}
_ => panic!("Tried to reduce bit array size without 2 operands"),
}
}
fn expression_operator_reduction(
(token_start, token, _token_end): Spanned,
left: UntypedExpr,
right: UntypedExpr,
) -> UntypedExpr {
if token == Token::Pipe {
let expressions = if let UntypedExpr::Pipeline { mut expressions } = left {
expressions.push(right);
expressions
} else {
vec1![left, right]
};
UntypedExpr::Pipeline { expressions }
} else {
match token_to_binop(&token) {View on GitHub (pinned to 15b07c7830)