BoundaryML/baml · error · anyhow::Error
Enum not found for variant
Error message
Enum not found for variant: {:?} What it means
from_vm_object converts a VmObject::Variant into a test-facing Object. Before reading the variant's name it dereferences the variant's enum handle from the VM object heap, expecting an enum. If the handle does not point to a VmObject::Enum, the internal representation is corrupt or the wrong object index was stored, so this bail fires.
Solutions
- Fix the code that constructs VmObject::Variant to store the correct enum index in the `enm` field
- Dump vm.objects[variant.enm] at the failure point to identify what type the index actually points to
- Check for GC/heap-compaction code that may invalidate Variant.enm indices
- Add a debug assertion when constructing variants that the handle resolves to VmObject::Enum
Example fix
// before
let VmObject::Enum(vm_enum) = &vm.objects[variant.enm] else {
anyhow::bail!("Enum not found for variant: {:?}", variant);
};
// after
let Some(vm_enum) = vm.objects.get(variant.enm) else {
anyhow::bail!("Enum index {} out of bounds for variant: {:?}", variant.enm, variant);
};
let VmObject::Enum(vm_enum) = vm_enum else {
anyhow::bail!("Handle {:?} points to {:?}, expected enum", variant.enm, vm_enum);
}; Defensive patterns
Strategy: type-guard
Validate before calling
fn is_enum_handle(vm: &Vm, idx: usize) -> bool {
matches!(vm.objects.get(idx), Some(VmObject::Enum(_)))
} Type guard
if let VmObject::Enum(vm_enum) = &vm.objects[variant.enm] { /* use vm_enum */ } else { /* skip or log */ } Try / catch
let obj = Object::from_vm_object(vm, variant).map_err(|e| { log::warn!("variant conversion failed: {e}"); e })?; Prevention
- Add assertions when constructing VmObject::Variant that the enm handle resolves to an enum
- Run VM snapshot/serialization tests after changing heap layout
- Avoid raw index handles; use typed handle wrappers
When it happens
Trigger: Calling from_vm_object on a VmObject::Variant whose `enm` field indexes a non-Enum object in vm.objects (e.g. a class or instance), typically due to a compiler/VM bug writing the wrong index into Variant.enm.
Common situations: VM developers testing watch/notification serialization after changing the layout of VmObject variants or enum heap indexing; stale indices after GC or heap compaction changes.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- cannot convert value
- unexpected type for enum value builder: %T
- attempted to read a property that has no defined type, this…
- ======================================== BAML Internal…
- baml.panics.AssertionFailed
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/0c9ddc3e25ecc7f5.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-vm/src/test.rs:119
anyhow::bail!("Class not found for instance: {:?}", instance);
};
let mut fields = BamlMap::new();
for (i, value) in instance.fields.iter().enumerate() {
let value = Value::from_vm_value(value, vm)?;
fields.insert(vm_class.field_names[i].clone(), value);
}
Ok(Object::Instance(Instance {
class: vm_class.name.clone(),
fields,
}))
}
VmObject::Variant(variant) => {
let VmObject::Enum(vm_enum) = &vm.objects[variant.enm] else {
anyhow::bail!("Enum not found for variant: {:?}", variant);
};
Ok(Object::Variant(Variant {
enm: vm_enum.name.clone(),
variant: vm_enum.variant_names[variant.index].clone(),
}))
}
VmObject::Media(media) => Ok(Object::Media(media.clone())),
VmObject::Function(f) => Ok(Object::Function(f.name.clone())),
VmObject::Class(c) => Ok(Object::Class(c.name.clone())),
VmObject::Enum(e) => Ok(Object::Enum(e.name.clone())),
_ => anyhow::bail!("Unsupported object type for testing: {:?}", obj),
}View on GitHub (pinned to bd85ce9dee)