{"record":{"id":"9a710dbfed29a202","repo":"BoundaryML/baml","slug":"package-enums-only-contains-enum-pointers","errorCode":null,"errorMessage":"Package.enums only contains enum pointers","messagePattern":"Package\\.enums only contains enum pointers","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm/src/package_reflect/reflect.rs","lineNumber":308,"sourceCode":"        bex_vm_types::TypeHead::new(class_ptr, class.type_tag),\n        Box::new([]),\n        class.ty_attr.clone(),\n    );\n    let ty_value = Value::object(vm.tlab.alloc_type(TypeValue::new(ty)));\n    super::type_kinds::alloc_kind_view(vm, baml_type::type_kind::TypeKind::Class, ty_value)\n}\n\nfn package_enum_type(vm: &mut BexVm, runtime_type: Option<HeapPtr>, enum_ptr: HeapPtr) -> Value {\n    if let Some(runtime_type) = runtime_type {\n        let ty_value = Value::object(runtime_type);\n        return super::type_kinds::alloc_kind_view(\n            vm,\n            baml_type::type_kind::TypeKind::Enum,\n            ty_value,\n        );\n    }\n    let Object::Enum(enm) = vm.get_object(enum_ptr) else {\n        unreachable!(\"Package.enums only contains enum pointers\")\n    };\n    let ty = RealizedTy::Enum(\n        bex_vm_types::TypeHead::new(enum_ptr, enm.type_tag),\n        enm.ty_attr.clone(),\n    );\n    let ty_value = Value::object(vm.tlab.alloc_type(TypeValue::new(ty)));\n    super::type_kinds::alloc_kind_view(vm, baml_type::type_kind::TypeKind::Enum, ty_value)\n}\n\nfn package_interface_type(\n    vm: &mut BexVm,\n    runtime_type: Option<HeapPtr>,\n    interface_ptr: HeapPtr,\n) -> Value {\n    if let Some(runtime_type) = runtime_type {\n        let ty_value = Value::object(runtime_type);\n        return super::type_kinds::alloc_kind_view(\n            vm,","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm/src/package_reflect/reflect.rs#L290-L326","documentation":"`package_enum_type` mirrors `package_class_type` for enums: it builds a reflected type from a pointer stored in `Package.enums`, asserting it always points to an `Object::Enum`. The `unreachable!` means the enum table contained a pointer to some other object — a corrupted or stale (un-forwarded) heap pointer, since the loader only stores enum pointers there.","triggerScenarios":"Calling `package_enum_type` (via `get_enum`/`enums`) when an enum slot in the package holds a moved, swept, or otherwise invalid pointer whose target object is no longer an `Object::Enum` — usually after GC forwarding failed to update the stored pointer.","commonSituations":"Reflection over Package.enums after a GC sweep without pointer forwarding; heap corruption from unsafe writes; tests that cache enum pointers across collection cycles.","solutions":["Ensure GC forwarding updates Package.enums pointers when enums move during sweep_and_forward.","Don't cache enum pointers across GC cycles; re-read them from the package after each sweep.","Audit unsafe code that could write non-enum objects into the package's enum table.","Run GC/reflection tests to reproduce and fix the forwarding regression."],"exampleFix":"// before\nlet enum_ptr = pkg.enums(vm)[0];\nforward_objects();\nlet ty = package_enum_type(vm, enum_ptr); // stale pointer panics\n// after\nlet enum_ptr = forwarding.get(&enum_ptr).copied().unwrap_or(enum_ptr);\nlet ty = package_enum_type(vm, enum_ptr);","handlingStrategy":"validation","validationCode":"fn is_enum(vm: &BexVm, p: HeapPtr) -> bool { matches!(vm.get_object(p), Object::Enum(_)) }","typeGuard":"fn as_enum<'a>(vm: &'a BexVm, p: HeapPtr) -> Option<&'a Enum> {\n    match vm.get_object(p) { Object::Enum(e) => Some(e), _ => None }\n}","tryCatchPattern":null,"preventionTips":["Ensure sweep_and_forward updates Package.enums pointers when enums move.","Don't cache enum heap pointers across collections; fetch them fresh per reflection call.","Run the GC/reflection test suite after any change to object forwarding."],"tags":["rust","vm","gc","invariant","reflection"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}