BoundaryML/baml · error
undefined variant: {enum_name_str}.{variant_str}
Error message
undefined variant: {enum_name_str}.{variant_str} What it means
When emitting an enum variant constant (`Constant::EnumVariant`), the compiler looks up the variant's index in `enum_variants` keyed by the enum's rendered name and variant string. Unlike the enum itself (which degrades gracefully to a Null constant when undefined), a missing variant entry panics: the enum object exists but this variant name is not registered for it. This means the source referenced a variant that doesn't exist on the (known) enum, or the variant table is out of sync.
Source
Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:2220
if enum_obj_idx.is_some() {
self.references.record(&enum_name_str);
}
let Some(enum_obj_idx) = enum_obj_idx else {
let idx = self.add_constant(ConstValue::Null);
let inst = self.emit(Instruction::LoadConst(idx));
self.set_operand(
inst,
OperandMeta::Const(format!("undefined_enum::{enum_name_str}.{variant}")),
);
return;
};
let variant_str = variant.to_string();
let variant_idx = *self
.enum_variants
.get(&enum_name_str)
.and_then(|variants| variants.get(&variant_str))
.unwrap_or_else(|| panic!("undefined variant: {enum_name_str}.{variant_str}"));
#[allow(clippy::cast_possible_wrap)]
let idx = self.add_constant(ConstValue::Int(variant_idx as i64));
let lc_inst = self.emit(Instruction::LoadConst(idx));
self.set_operand(
lc_inst,
OperandMeta::Const(format!("{enum_name_str}.{variant_str}")),
);
let inst = self.emit(Instruction::AllocVariant(ObjectIndex::from_raw(
enum_obj_idx,
)));
self.set_operand(inst, OperandMeta::Object(enum_name_str));
}
}
}
// ========================================================================
// Store EmissionView on GitHub (pinned to bd85ce9dee)
Solutions
- Check the spelling of the variant at the use site against the enum declaration and fix the typo
- If the variant was renamed/removed, update all references to the new name
- Clear incremental caches and rebuild so `enum_variants` matches the current declarations
- If the enum is declared in multiple packages, resolve the name collision or align the definitions
- Consider matching the enum-constant path's graceful behavior (emit an error diagnostic instead of panicking) if you maintain the compiler
Example fix
// before (BAML)
let c = Color\u{2e}Grean;
// after
let c = Color.Green; Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: validate enum variant references against declared variants
fn validate_variant(enum_variants: &HashMap<String, HashMap<String, usize>>, enum_name: &str, variant: &str) -> Result<(), String> {
enum_variants
.get(enum_name)
.and_then(|v| v.get(variant))
.map(|_| ())
.ok_or_else(|| format!("undefined variant: {enum_name}.{variant}"))
} Type guard
fn variant_exists(enum_variants: &HashMap<String, HashMap<String, usize>>, enum_name: &str, variant: &str) -> bool {
enum_variants.get(enum_name).is_some_and(|v| v.contains_key(variant))
} Try / catch
match std::panic::catch_unwind(|| compile(inputs)) {
Ok(out) => out,
Err(_) => {
eprintln!("compile panicked (likely stale variant table); rebuilding from scratch");
clean_cache();
compile(inputs)
}
} Prevention
- Double-check variant spellings against the enum declaration
- Rebuild after removing or renaming enum variants
- Avoid declaring two enums with the same name across packages
- Use editor tooling/autocomplete for variant names to avoid typos
When it happens
Trigger: Compiling code like `MyEnum.SomeVariant` where `MyEnum` is registered but `SomeVariant` is not among its declared variants (typo or removed variant), or where the `enum_variants` map for that enum was populated from a stale/different definition that lacks the variant (stale incremental state, cross-package enum with divergent definitions).
Common situations: Typos in variant names at the use site; removing/renaming an enum variant while other code (or a stale cache) still references the old name; two packages declaring the same enum name with different variant sets.
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
- type_arg_templates count fits in u16
- ntypeargs fits in u16
- interface body has no Pass-1 slot: {item}
- {what}: {item}
- undefined global item: {name_str}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/2830a37e82075aad.
Report an issue: GitHub.