gleam-lang/gleam · error

Token could not be converted to binop.

Error message

Token could not be converted to binop.

What it means

An internal parser panic in `expression_operator_reduction` (compiler-core/src/parse.rs). This function maps an operator token to a binary-operation AST node while building operator-precedence expressions; the `_` arm panics when a token that reached the binop-construction path cannot be converted into a binary operator. It should be unreachable because operator filtering happens earlier in the precedence-climbing loop.

Solutions

  1. Capture the input program that panics and report it upstream with a minimal repro.
  2. If contributing: add the missing token-to-binop mapping in `expression_operator_reduction` before the `_ => panic!` arm.
  3. Update to the newest gleam-core release; the panic may have been fixed upstream.

Example fix

// before
_ => {
    panic!("Token could not be converted to binop.")
}
// after
(token, ..) if is_new_operator(token) => BinOp::NewOperator,
_ => {
    panic!("Token could not be converted to binop.")
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

// Rust: assert the token is a known binop token before reduction
fn is_binop_token(t: &Token) -> bool {
    matches!(t, Token::Plus | Token::Minus | Token::Star /* ...all binop tokens */)
}

Try / catch

// Panic is unrecoverable by design; in tooling wrap parsing in catch_unwind.
std::panic::catch_unwind(|| parse_expression(src))

Prevention

When it happens

Trigger: The precedence reducer receives a `Spanned` token in the operator position that is not one of the recognized binary operators (e.g. after a change to the token set or precedence table), so the final match falls through to `_`.

Common situations: Seen by Gleam compiler contributors after adding/renaming tokens or operators without updating `expression_operator_reduction`, or by fuzzers feeding pathological token sequences. Not reachable through normal `gleam build` usage of supported syntax.

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 gleam-lang/gleam@15b07c7830 (2026-09-14). Data as JSON: /api/errors/83d4d3aa16fe1a80. Report an issue: GitHub.

Appendix: source

Thrown at compiler-core/src/parse.rs:5207

            expressions
        } else {
            vec1![left, right]
        };
        UntypedExpr::Pipeline { expressions }
    } else {
        match token_to_binop(&token) {
            Some(operator) => UntypedExpr::BinOp {
                location: SrcSpan {
                    start: left.location().start,
                    end: right.location().end,
                },
                operator,
                operator_start: token_start,
                left: Box::new(left),
                right: Box::new(right),
            },
            _ => {
                panic!("Token could not be converted to binop.")
            }
        }
    }
}

fn clause_guard_reduction(
    (start, token, _end): Spanned,
    left: UntypedClauseGuard,
    right: UntypedClauseGuard,
) -> UntypedClauseGuard {
    let location = SrcSpan {
        start: left.location().start,
        end: right.location().end,
    };
    let left = Box::new(left);
    let right = Box::new(right);
    let operator = token_to_binop(&token).expect("Token could not be converted to binop.");
    UntypedClauseGuard::BinaryOperator {

View on GitHub (pinned to 15b07c7830)