BoundaryML/baml · error

Expected a

Error message

Expected a {}

What it means

The optional/required variant of next_pair! errors with 'Expected a {}' when the pair iterator is exhausted but a required rule was still expected. Note the DECLARED AS metadata shows this message string is also surfaced by CLI version-selector helpers (selector_origin etc.) in baml's main.rs, but the source shown is the formatter macro's None branch.

Solutions

  1. Complete/truncate-fix the .baml source so the expected construct is present.
  2. Use a baml-language CLI version matching the parser that produced the AST.
  3. Report the schema snippet as a formatter bug if the file parses cleanly with baml-cli parse.

Example fix

// before (truncated source)
function Foo(a in
// after
function Foo(a in string) {
  a
}
Defensive patterns

Strategy: try-catch

Try / catch

let formatted = format_schema(source, &options)
    .or_else(|_| Ok::<String, anyhow::Error>(source.to_string()))?;

Prevention

When it happens

Trigger: A required rule expected by next_pair! is missing because the parse tree ended earlier than the formatter's structural walk anticipated — truncated or syntactically unusual (but parseable) BAML source.

Common situations: Formatting a partially written or truncated .baml file, or grammar/formatter version mismatch where the expected trailing rule no longer exists.

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

Appendix: source

Thrown at engine/baml-lib/ast/src/formatter/mod.rs:72

                Some(pair) => {
                    if pair.as_rule() == Rule::NEWLINE {
                        $pairs.next();
                        continue;
                    }
                    if pair.as_rule() != $rule {
                        break Err(anyhow!(
                            "Expected a {:?}, got a {:?} ({}:{})",
                            $rule,
                            pair.as_rule(),
                            file!(),
                            line!()
                        ));
                    } else {
                        $pairs.next();
                        break Ok(pair);
                    }
                }
                None => break Err(anyhow!("Expected a {}", stringify!($rule))),
            }
        }
    }};

    ($pairs:ident, $rule:expr, optional) => {{
        match $pairs.peek() {
            Some(pair) => {
                if pair.as_rule() == $rule {
                    $pairs.next()
                } else {
                    None
                }
            }
            None => None,
        }
    }};
}

View on GitHub (pinned to bd85ce9dee)