BoundaryML/baml · error
undefined enum: {name}
Error message
undefined enum: {name} What it means
Panic when compiling an enum member access `EnumName.Variant`: the variant itself resolved (it exists in `self.enums`), but the enum's name is missing from the globals table, so codegen cannot emit the `LoadGlobal` needed to materialize the enum type at runtime. This indicates enum registration and the globals table are inconsistent across compiler phases.
Source
Thrown at engine/baml-compiler/src/codegen.rs:1158
self.emit(
match base.meta().1.as_ref().expect("must have a resolved type") {
TypeIR::List(_, _) => Instruction::LoadArrayElement,
TypeIR::Map(_, _, _) => Instruction::LoadMapElement,
_ => panic!("array access should be either map or array."),
},
);
}
thir::Expr::FieldAccess { base, field, .. } => {
// Direct enum access: Share.Rectangle
if let thir::Expr::Var(name, _) = base.as_ref() {
if let Some(enm) = self.enums.get(name) {
let Some(variant_index) = enm.get(field) else {
panic!("undefined enum variant: {name}.{field}");
};
let Some(enum_index) = self.globals.get(name) else {
panic!("undefined enum: {name}");
};
let const_index = self.add_constant(Value::Int(*variant_index as i64));
self.emit(Instruction::LoadConst(const_index));
let allocation_instruction =
self.emit(Instruction::AllocVariant(ObjectIndex::from_raw(usize::MAX)));
// TODO: Confusing name because of class alloc reuse.
self.class_alloc_patch_list.push(AllocInstancePatch {
location: allocation_instruction,
global: *enum_index,
});
return;
}
}
View on GitHub (pinned to bd85ce9dee)
Solutions
- Verify the enum is declared/imported in the same compilation unit so it gets registered as a global
- Reorder or re-register declarations so the enum is registered before expressions referencing it are compiled
- Check for duplicate definitions or shadowing that suppress global registration
- If the enum is plainly declared, report a compiler bug: globals registration missed the enum
Example fix
// before
// enum Share { ... } defined in another file, not imported
let s = Share.Rectangle
// after
import "./share.baml" // brings enum Share into the unit
let s = Share.Rectangle Defensive patterns
Strategy: validation
Validate before calling
// Ensure enums referenced via member access are registered in the compile unit
fn ensure_enum_registered(unit: &Unit, enum_name: &str) -> Result<(), String> {
if unit.enums.contains_key(enum_name) && unit.globals.contains_key(enum_name) { Ok(()) }
else { Err(format!("enum `{enum_name}` is not registered in this compilation unit")) }
} Prevention
- Import files that define enums you reference
- Do a full rebuild after adding new enum files to avoid stale registration
- Check import lists whenever a member access like `Enum.Variant` fails
When it happens
Trigger: Compiling `Expr::FieldAccess` on a base `Var(name)` where `self.enums` contains `name` but `self.globals.get(name)` is None — the enum was collected during resolution but never registered as a global before codegen.
Common situations: Enums defined dynamically or in files not added to the global registry; partial compilation where some declarations were skipped; compiler bugs where enum collection and global registration use different visibility rules.
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
- undefined enum variant: {name}.{field}
- undefined enum: {enum_name}
- undefined variant: {enum_name}.{variant}
- Field access on non-class type
- undefined class: {class_name}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/8e51e9965c1a699b.
Report an issue: GitHub.