BoundaryML/baml · error
undefined enum variant: {name}.{field}
Error message
undefined enum variant: {name}.{field} What it means
Panic when compiling a field access like `EnumName.Variant` where the base resolves to a known enum but the field name is not a variant of that enum. Codegen needs a variant index to emit the enum constant; a missing variant means the name resolution/typecheck stages let an invalid enum variant through, so codegen aborts.
Source
Thrown at engine/baml-compiler/src/codegen.rs:1154
self.compile_expression(base);
self.compile_expression(index);
// Determine if it's an array or map and emit appropriate instruction
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,
});
View on GitHub (pinned to bd85ce9dee)
Solutions
- Check the enum definition and correct the variant name spelling
- Update references after renaming/removing an enum variant
- If the enum is defined in an imported file, verify you are referencing the correct enum version
- If the variant exists, file a compiler bug: enum tables are inconsistent between phases
Example fix
// before let s = Share.Rectengle // after let s = Share.Rectangle
Defensive patterns
Strategy: validation
Validate before calling
// Verify the variant exists on the enum before emitting EnumName.Variant
fn validate_enum_access(enum_def: &Enum, variant: &str) -> Result<(), String> {
if enum_def.variants.iter().any(|v| v.name == variant) { Ok(()) }
else { Err(format!("variant `{}` not defined on enum `{}`", variant, enum_def.name)) }
} Prevention
- Use editor completion for enum variants instead of typing them from memory
- Regenerate/stale-check after renaming enum variants
- Keep enum definitions centralized and grep usages on rename
When it happens
Trigger: Compiling `Expr::FieldAccess` where `base` is a `Var` found in `self.enums`, but `enm.get(field)` returns None — e.g. `Share.Rectengle` when the enum only defines `Rectangle`.
Common situations: Typos in enum variant names; variants removed or renamed in the enum definition while expression references were not updated; enum defined in another file with a divergent variant list.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- undefined enum: {name}
- 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/876646683bc0349e.
Report an issue: GitHub.