{"record":{"id":"1e11b9f4bb75f22d","repo":"BoundaryML/baml","slug":"method-calls-must-be-identifiers","errorCode":null,"errorMessage":"method calls must be identifiers","messagePattern":"method calls must be identifiers","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-compiler/src/codegen.rs","lineNumber":1292,"sourceCode":"                    } else {\n                        args.len()\n                    };\n\n                    self.emit(Instruction::DispatchFuture(count));\n                    self.emit(Instruction::Await);\n                } else {\n                    self.emit(Instruction::Call(args.len()));\n                }\n            }\n\n            thir::Expr::MethodCall {\n                receiver,\n                method,\n                args,\n                ..\n            } => {\n                let thir::Expr::Var(method, _) = method.as_ref() else {\n                    panic!(\"method calls must be identifiers\");\n                };\n\n                let func_name = match receiver.meta().1.as_ref() {\n                    Some(TypeIR::Class {\n                        name: class_name, ..\n                    }) => format!(\"{class_name}.{method}\"),\n\n                    Some(TypeIR::List(_, _)) => format!(\"baml.Array.{method}\"),\n\n                    Some(TypeIR::Map(_, _, _)) => format!(\"baml.Map.{method}\"),\n\n                    Some(TypeIR::Primitive(TypeValue::String, _)) => {\n                        format!(\"baml.String.{method}\")\n                    }\n\n                    Some(TypeIR::Primitive(TypeValue::Float, _))\n                    | Some(TypeIR::Primitive(TypeValue::Int, _)) => {\n                        format!(\"baml.Float.{method}\")","sourceCodeStart":1274,"sourceCodeEnd":1310,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-compiler/src/codegen.rs#L1274-L1310","documentation":"Method-call syntax requires the method component to be a plain identifier (Expr::Var). If the parser produced a method position holding any other expression, the code generator panics, since it constructs the dispatched name as '{ClassName}.{method}' and needs a literal method name.","triggerScenarios":"Compiling a MethodCall expression whose method field is not Expr::Var — e.g. computed method names or nested call results in the method position. Usually only reachable via malformed AST or exotic generated code, since normal syntax cannot express this.","commonSituations":"Mostly compiler-internal: hand-edited or generated THIR, parser/codegen desync bugs, or fuzzed inputs. Rarely hit by hand-written BAML.","solutions":["Rewrite the call using standard method syntax with a literal method name (receiver.method(args))","Verify the .baml source contains a normal identifier after the dot","If valid source triggers this, it is a parser/codegen bug — report it with the input","Check for macros or code generation steps emitting non-identifier method positions"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn validate_method_call(mc: &MethodCall) -> Result<(), String> {\n    match mc.method.as_ref() { Expr::Var(_, _) => Ok(()), _ => Err(\"method position must be an identifier\".into()) }\n}","typeGuard":"fn is_identifier_method(mc: &MethodCall) -> bool { matches!(mc.method.as_ref(), Expr::Var(_, _)) }","tryCatchPattern":null,"preventionTips":["Use standard receiver.method(args) syntax with literal method names","Avoid generated or hand-edited AST/THIR with computed method positions","If valid source triggers this, report a parser/codegen bug with a reproducing example"],"tags":["compiler","codegen","panic","method-call"],"backgroundTag":"invalid-argument-format","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}