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 Emission

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Check the spelling of the variant at the use site against the enum declaration and fix the typo
  2. If the variant was renamed/removed, update all references to the new name
  3. Clear incremental caches and rebuild so `enum_variants` matches the current declarations
  4. If the enum is declared in multiple packages, resolve the name collision or align the definitions
  5. 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

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


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/2830a37e82075aad. Report an issue: GitHub.