BoundaryML/baml · error

Encountered impossible class constructor during parsing

Error message

Encountered impossible class constructor during parsing

What it means

A panic in parse_class_constructor when the first child token of a class_constructor pair is neither Rule::identifier nor Rule::path_identifier. The grammar is expected to constrain the first token to those two rules; anything else triggers panic!("Encountered impossible class constructor during parsing"). This is a grammar/parser desynchronization bug rather than a designed user-facing error.

Source

Thrown at engine/baml-lib/ast/src/parser/parse_expression.rs:652

    if let Some(value) = value {
        value
    } else {
        unreachable!("Encountered impossible jinja expression during parsing")
    }
}

pub fn parse_class_constructor(token: Pair<'_>, diagnostics: &mut Diagnostics) -> Expression {
    assert_correct_parser(&token, &[Rule::class_constructor], diagnostics);

    let span = diagnostics.span(token.as_span());
    let mut tokens = token.into_inner();

    let ident_token = tokens.next().expect("Guaranteed by the grammar");

    let class_name = match ident_token.as_rule() {
        Rule::identifier => parse_identifier(ident_token, diagnostics),
        Rule::path_identifier => parse_path_identifier(ident_token, diagnostics),
        _ => panic!("Encountered impossible class constructor during parsing"),
    };

    let mut fields = Vec::new();
    while let Some(field_or_close_bracket) = tokens.next() {
        if field_or_close_bracket.as_str() == "}" {
            break;
        }
        if field_or_close_bracket.as_str() == "," {
            continue;
        }
        if field_or_close_bracket.as_rule() == Rule::NEWLINE {
            continue;
        }

        assert_correct_parser(
            &field_or_close_bracket,
            &[Rule::class_field_value_pair],
            diagnostics,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Fix the class constructor declaration in your .bml file at the reported span (name must be a plain or dotted identifier)
  2. Report the reproducing input to BAML as a parser bug
  3. Update the match arms in parse_class_constructor if you modified the grammar to allow new rule types
  4. Pin a BAML version where grammar and parser agree

Example fix

// before
class 123Invalid { }
// after
class ValidName { }
Defensive patterns

Strategy: validation

Validate before calling

// Reject class names that are not identifiers before parsing
fn valid_class_name(src: &str) -> bool {
    src.lines().filter_map(|l| l.trim().strip_prefix("class "))
        .all(|rest| {
            let name: String = rest.chars().take_while(|c| c.is_alphanumeric() || *c == '_' || *c == '.').collect();
            !name.is_empty() && name.chars().next().map_or(false, |c| c.is_alphabetic() || c == '_')
        })
}

Type guard

fn is_identifier(s: &str) -> bool {
    !s.is_empty()
        && s.chars().next().map_or(false, |c| c.is_alphabetic() || c == '_')
        && s.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '.')
}

Try / catch

let ok = std::panic::catch_unwind(|| parse_class_constructor(pair, &mut diagnostics));
if ok.is_err() { diagnostics.push("unrecognized class constructor name rule"); }

Prevention

When it happens

Trigger: parse_class_constructor receiving a class_constructor pair whose first inner token is an unexpected rule (e.g. a keyword or literal after a grammar change).

Common situations: Hit when BAML grammar .pest rules are edited without updating the match arms in the parser, or when hand-crafting parse trees in tests.

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/3bf64e125e66baab. Report an issue: GitHub.