BoundaryML/baml · error
undefined class: {class_name}
Error message
undefined class: {class_name} What it means
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.
Source
Thrown at engine/baml-compiler/src/codegen.rs:601
thir::Statement::Declare { name, .. } => {
self.declare_mut(name);
}
thir::Statement::Assign { left, value, .. } => {
match left {
thir::Expr::Var(name, _) => {
self.compile_expression_with_block_behavior(value, true);
self.emit(Instruction::StoreVar(self.locals[name]));
}
thir::Expr::FieldAccess { base, field, meta: _ } => {
// Get class name from type metadata
let class_name = match base.meta().1.as_ref() {
Some(TypeIR::Class { name, .. }) => name,
_ => panic!("Field access on non-class type"),
};
// Resolve field index
let Some(resolved_fields) = self.classes.get(class_name) else {
panic!("undefined class: {class_name}");
};
let Some(&field_index) = resolved_fields.get(field) else {
panic!("undefined field: {class_name}.{field}");
};
// Generate bytecode: load base, load value, store field
self.compile_expression(base);
self.compile_expression_with_block_behavior(value, true);
self.emit(Instruction::StoreField(field_index));
}
thir::Expr::ArrayAccess {base, index, meta: _} => {
self.compile_expression(base);
self.compile_expression(index);
self.compile_expression_with_block_behavior(value, true);
self.emit(match base.meta().1.as_ref().expect("must have a resolved type") {
TypeIR::List(_, _) => Instruction::StoreArrayElement,View on GitHub (pinned to bd85ce9dee)
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.
Example fix
// 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 }; Defensive patterns
Strategy: validation
Validate before calling
// 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} Type guard
fn class_registered(classes: &HashMap<String, BamlClass>, name: &str) -> bool {\n classes.contains_key(name)\n} Try / catch
let Some(resolved_fields) = self.classes.get(class_name) else {\n return Err(compile_error!("undefined class: {class_name}")); // diagnostic instead of panic\n}; Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Field access on non-class type
- undefined field: {class_name}.{field}
- array access should be either map or array.
- undefined function: {name}
- watch codegen error: undefined variable: {variable}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/aed44c4aabe63892.
Report an issue: GitHub.