{"record":{"id":"aed44c4aabe63892","repo":"BoundaryML/baml","slug":"undefined-class-class-name","errorCode":null,"errorMessage":"undefined class: {class_name}","messagePattern":"undefined class: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-compiler/src/codegen.rs","lineNumber":601,"sourceCode":"            thir::Statement::Declare { name, .. } => {\n                self.declare_mut(name);\n            }\n            thir::Statement::Assign { left, value, .. } => {\n                match left {\n                    thir::Expr::Var(name, _) => {\n                        self.compile_expression_with_block_behavior(value, true);\n                        self.emit(Instruction::StoreVar(self.locals[name]));\n                    }\n                    thir::Expr::FieldAccess { base, field, meta: _ } => {\n                        // Get class name from type metadata\n                        let class_name = match base.meta().1.as_ref() {\n                            Some(TypeIR::Class { name, .. }) => name,\n                            _ => panic!(\"Field access on non-class type\"),\n                        };\n\n                        // Resolve field index\n                        let Some(resolved_fields) = self.classes.get(class_name) else {\n                            panic!(\"undefined class: {class_name}\");\n                        };\n                        let Some(&field_index) = resolved_fields.get(field) else {\n                            panic!(\"undefined field: {class_name}.{field}\");\n                        };\n\n                        // Generate bytecode: load base, load value, store field\n                        self.compile_expression(base);\n                        self.compile_expression_with_block_behavior(value, true);\n                        self.emit(Instruction::StoreField(field_index));\n                    }\n                    thir::Expr::ArrayAccess {base, index, meta: _} => {\n\n                        self.compile_expression(base);\n                        self.compile_expression(index);\n                        self.compile_expression_with_block_behavior(value, true);\n\n                        self.emit(match base.meta().1.as_ref().expect(\"must have a resolved type\") {\n                            TypeIR::List(_, _) => Instruction::StoreArrayElement,","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-compiler/src/codegen.rs#L583-L619","documentation":"After confirming the base is a class, codegen looks up that class's fields in self.classes (the compiled class table) to resolve the field index. If the class name is absent from the table, the compiler panics with 'undefined class: {class_name}'. The class should have been declared and registered before any field access compiles.","triggerScenarios":"compile_statement processes FieldAccess whose base type is TypeIR::Class{name}, but self.classes has no entry for that name — e.g. the class was referenced but never defined, or class collection ran before/outside the current compilation unit.","commonSituations":"Typo in class name in BAML source; using a class defined in another module not included in compilation; class defined after use where ordering matters; codegen not registering classes from generated/dependency schemas.","solutions":["Define the class in your BAML source, or correct the class name spelling to match the definition.","Ensure the module containing the class is included in the compilation/generation set.","Fix compiler ordering so all classes are collected into self.classes before statement codegen.","Improve the diagnostic: map the panic to a user-facing compile error with the span of the field access."],"exampleFix":"// before: field access on undefined class\\nlet a = UndefinedClass { x: 1 };\\n// after: define the class first\\nclass DefinedClass { x int }\\nlet a = DefinedClass { x: 1 };","handlingStrategy":"validation","validationCode":"// before codegen, verify every referenced class is registered\\nfor name in &referenced_classes {\\n    assert!(classes.contains_key(name), \"class {name} referenced but not declared\");\\n}","typeGuard":"fn class_registered(classes: &HashMap<String, BamlClass>, name: &str) -> bool {\\n    classes.contains_key(name)\\n}","tryCatchPattern":"let Some(resolved_fields) = self.classes.get(class_name) else {\\n    return Err(compile_error!(\"undefined class: {class_name}\")); // diagnostic instead of panic\\n};","preventionTips":["Declare all classes used by field access in the same compilation set.","Spell-check class names; IDE autocomplete helps.","Ensure class collection happens before statement codegen for all modules.","Add a compile-time pass validating every referenced class exists."],"tags":["compiler","codegen","panic"],"backgroundTag":"class-not-found","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"}