BoundaryML/baml · critical

undefined variant: {enum_name}.{variant}

Error message

undefined variant: {enum_name}.{variant}

What it means

Panic in alloc_enum_variant: the enum exists in enum_object_indices but the specific variant name is missing from enum_variants[enum_name]. The compiler allocated the enum object yet has no variant index for the requested variant, so the variant load cannot be lowered. This is a name-resolution failure between the referenced variant and the compiler's variant table.

Source

Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:3567

    fn init_field(&mut self, field_idx: usize, name: &str) -> Result<(), Self::Error> {
        let idx = self.emit(Instruction::InitField(field_idx));
        self.set_operand(idx, OperandMeta::Field(name.to_string()));
        Ok(())
    }

    fn alloc_enum_variant(&mut self, enum_name: &str, variant: &str) -> Result<(), Self::Error> {
        let enum_obj_idx = self
            .enum_object_indices
            .get(enum_name)
            .copied()
            .unwrap_or_else(|| panic!("undefined enum: {enum_name}"));

        let variant_idx = self
            .enum_variants
            .get(enum_name)
            .and_then(|variants| variants.get(variant))
            .copied()
            .unwrap_or_else(|| panic!("undefined variant: {enum_name}.{variant}"));

        #[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}.{variant}")),
        );
        let inst = self.emit(Instruction::AllocVariant(ObjectIndex::from_raw(
            enum_obj_idx,
        )));
        self.set_operand(inst, OperandMeta::Object(enum_name.to_string()));
        Ok(())
    }

    fn discriminant(&mut self) -> Result<(), Self::Error> {
        self.emit(Instruction::Discriminant);
        Ok(())

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Fix the variant name to match the enum's declared variants.
  2. Regenerate client code after the enum's variant set changes.
  3. Add the missing variant to the enum definition if it was removed by mistake.
  4. Align BAML schema versions across client and server so both sides know the variant.

Example fix

// before: variant that no longer exists
let s = Status.Pendng;
// after: corrected spelling
let s = Status.Pending;
Defensive patterns

Strategy: validation

Validate before calling

// verify the variant exists on the enum before use
let variants: Vec<&str> = project.enum_variants("Status");
assert!(variants.contains(&"Pending"), "Status has no variant Pending");

Type guard

fn variant_exists(project: &Project, enum_name: &str, variant: &str) -> bool {
    project.enum_variants(enum_name).contains(variant)
}

Try / catch

// compiler panic — validate names at generation/lint time
if !variant_exists(project, "Status", "Pending") {
    regenerate_client_code();
}

Prevention

When it happens

Trigger: Referencing a variant that does not exist on the enum (typo, removed variant, or variant added in a newer schema version while generated/older code still references the old set).

Common situations: Typos in variant names, refactoring enum variants without updating all references, version drift between BAML clients/server schema where the variant list differs.

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/d9eac88d2e97be61. Report an issue: GitHub.