BoundaryML/baml · critical

undefined enum: {enum_name}

Error message

undefined enum: {enum_name}

What it means

Panic in alloc_enum_variant: the requested enum name has no entry in the emitter's enum_object_indices map, so no enum object was allocated for it. The compiler can only emit enum variant loads for enums it allocated during the pre-pass; referencing an unknown enum name is an internal lookup failure.

Source

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

        ntypeargs: u16,
        field_count: usize,
    ) -> Result<(), Self::Error> {
        self.emit_init_instance(class_name, ntypeargs, field_count);
        Ok(())
    }

    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,
        )));

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure the file/module defining the enum is included in the compilation unit.
  2. Fix or regenerate references that use the old enum name after a rename.
  3. Verify the enum-allocation pre-pass visits the enum's definition.
  4. Check imports/includes so the referenced enum actually resolves.

Example fix

// before: referencing a renamed enum
let v = OldEnum.VariantA;
// after
let v = NewEnum.VariantA;
Defensive patterns

Strategy: validation

Validate before calling

// before referencing an enum, ensure its definition compiles in-unit
assert!(project.enums().contains_key("MyEnum"), "enum MyEnum not found in compilation unit");

Type guard

fn enum_exists(project: &Project, name: &str) -> bool {
    project.enums().contains_key(name)
}

Try / catch

// compiler panic — verify references ahead of compilation
match resolve_enum(name) {
    Some(_) => compile_referring_code(),
    None => fix_or_remove_reference(name),
}

Prevention

When it happens

Trigger: Emitting an enum variant access for enum_name that was never registered — e.g. the enum is defined in another module/file that was not compiled into the same unit, or the enum was deleted/renamed while references remain.

Common situations: Stale references after renaming an enum, generated code referencing an enum from an uncompiled dependency, or compiler pre-pass skipping the enum's defining file.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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