{"record":{"id":"1359b7e4e4aabdc2","repo":"BoundaryML/baml","slug":"unexpected-method-call-rule","errorCode":null,"errorMessage":"Unexpected method call rule: {:?}","messagePattern":"Unexpected method call rule: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-lib/ast/src/parser/parse_expression.rs","lineNumber":127,"sourceCode":"                                unreachable!(\"expected function call when parsing method call\")\n                            }\n                        },\n\n                        Rule::generic_fn_app => match parse_generic_fn_app(inner, diagnostics)? {\n                            Expression::App(fn_call) => Expression::MethodCall {\n                                receiver: Box::new(left),\n                                method: fn_call.name,\n                                args: fn_call.args,\n                                type_args: fn_call.type_args,\n                                span: span.clone(),\n                            },\n\n                            _ => {\n                                unreachable!(\"expected function call when parsing method call\")\n                            }\n                        },\n\n                        _ => unreachable!(\"Unexpected method call rule: {:?}\", inner.as_rule()),\n                    }\n                }\n                _ => unreachable!(\"Unexpected postfix operator: {:?}\", operator.as_rule()),\n            })\n        })\n        .map_infix(|left, operator, right| {\n            let operator = match operator.as_rule() {\n                Rule::EQ => BinaryOperator::Eq,\n                Rule::NEQ => BinaryOperator::Neq,\n                Rule::LT => BinaryOperator::Lt,\n                Rule::LTEQ => BinaryOperator::LtEq,\n                Rule::GT => BinaryOperator::Gt,\n                Rule::GTEQ => BinaryOperator::GtEq,\n                Rule::ADD => BinaryOperator::Add,\n                Rule::SUB => BinaryOperator::Sub,\n                Rule::MUL => BinaryOperator::Mul,\n                Rule::DIV => BinaryOperator::Div,\n                Rule::MOD => BinaryOperator::Mod,","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-lib/ast/src/parser/parse_expression.rs#L109-L145","documentation":"This is a `unreachable!()` panic on the fallback arm of the postfix-operator match in `parse_expression`. The grammar only expects function application (`fn_app`), generic function application (`generic_fn_app`), and field access as postfix operators; when `map_postfix` receives any other operator rule, the grammar/code contract is broken and the parser panics. It is an internal invariant, not a user-facing syntax error.","triggerScenarios":"The pratt parser's `map_postfix` receives an operator Pair whose rule is neither `fn_app`, `generic_fn_app`, nor the field-access rule — only possible after a .pest grammar change adding a new postfix operator (e.g. indexing `a[i]`, `?.`) that `parse_expression` does not yet map.","commonSituations":"Using a newly added postfix syntax in BAML against a parser that doesn't implement it; contributors adding index-access or optional-chaining rules to baml.pest without extending `map_postfix`.","solutions":["Rewrite the BAML expression to use only supported postfix syntax: method calls `x.m()`, generic calls `x.m<T>()`, and field access `x.f`","If you added a new postfix rule to baml.pest, add a match arm in `map_postfix` in parse_expression.rs handling it (or emit diagnostics instead of panicking)","Upgrade/downgrade BAML so grammar and parser are from the same version"],"exampleFix":"// before (unsupported postfix syntax triggers panic)\nlet v = arr[0];\n// after (use an API that supports indexing, or loop to access elements)\nlet v = first(arr);","handlingStrategy":"validation","validationCode":"// Restrict generated BAML postfix syntax to calls and field access:\nfunction assertSupportedPostfix(expr) {\n  if (/[\\[\\?\\?]/.test(expr) && !/^\\s*\\w+\\s*(\\.|\\()/.test(expr)) {\n    throw new Error('Unsupported postfix syntax (indexing/optional chaining) panics the BAML parser: ' + expr);\n  }\n}","typeGuard":"const usesOnlySupportedPostfix = (expr) => !/[\\[\\?]/.test(expr.replace(/\\b\\w+\\(/g, ''));","tryCatchPattern":"catch (panicOutput) {\n  if (String(panicOutput).includes('Unexpected postfix operator')) {\n    logParserBug('grammar added a postfix op the parser cannot map', panicOutput);\n    return null;\n  }\n  throw panicOutput;\n}","preventionTips":["Use only method calls, generic calls, and dot field access as postfix operations in BAML","Extend map_postfix in the same change that adds a postfix rule to baml.pest","Version-align grammar and parser crates","Add grammar-coverage tests for every postfix rule"],"tags":["parser","panic","postfix-operator","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}