BoundaryML/baml · error

Package.classes only contains class pointers

Error message

Package.classes only contains class pointers

What it means

`package_class_type` builds a reflected type for a class obtained from a package's `Package.classes` list. The `unreachable!` fires if the stored pointer does not point to an `Object::Class` — meaning the package's classes table was corrupted or populated with a non-class object. This is a hard internal invariant: the library only ever stores class pointers there.

Source

Thrown at baml_language/crates/bex_vm/src/package_reflect/reflect.rs:287

        interface: &Interface,
        member: &baml_type::Name,
        fuel: u32,
    ) -> baml_type::normalize::ProjectionStep<bex_vm_types::TypeHead> {
        TypeContext::project(self.vm, base, interface, member, fuel)
    }
}

fn package_class_type(vm: &mut BexVm, runtime_type: Option<HeapPtr>, class_ptr: HeapPtr) -> Value {
    if let Some(runtime_type) = runtime_type {
        let ty_value = Value::object(runtime_type);
        return super::type_kinds::alloc_kind_view(
            vm,
            baml_type::type_kind::TypeKind::Class,
            ty_value,
        );
    }
    let Object::Class(class) = vm.get_object(class_ptr) else {
        unreachable!("Package.classes only contains class pointers")
    };
    let ty = RealizedTy::Class(
        bex_vm_types::TypeHead::new(class_ptr, class.type_tag),
        Box::new([]),
        class.ty_attr.clone(),
    );
    let ty_value = Value::object(vm.tlab.alloc_type(TypeValue::new(ty)));
    super::type_kinds::alloc_kind_view(vm, baml_type::type_kind::TypeKind::Class, ty_value)
}

fn package_enum_type(vm: &mut BexVm, runtime_type: Option<HeapPtr>, enum_ptr: HeapPtr) -> Value {
    if let Some(runtime_type) = runtime_type {
        let ty_value = Value::object(runtime_type);
        return super::type_kinds::alloc_kind_view(
            vm,
            baml_type::type_kind::TypeKind::Enum,
            ty_value,
        );

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Audit the GC/forwarding path: ensure class pointers in Package.classes are updated on object moves before reflection reads them.
  2. Verify no unsafe code writes non-class objects into the package's classes table.
  3. Reproduce with the GC test suite and check whether the pointer was swept/forwarded correctly (see dynamic_dispatch_entries tests).
  4. If hit in a test, follow forwarding entries for stored pointers before calling reflection APIs.

Example fix

// before: using a stale pointer captured before a GC
let class_ptr = package.classes(vm)[0];
sweep_and_forward();
let ty = package_class_type(vm, class_ptr); // panics: pointer moved
// after: re-read pointers after the sweep, or follow forwarding
let class_ptr = forwarding.get(&class_ptr).copied().unwrap_or(class_ptr);
let ty = package_class_type(vm, class_ptr);
Defensive patterns

Strategy: validation

Validate before calling

// verify a class pointer is still valid after GC before reflection
fn is_class(vm: &BexVm, p: HeapPtr) -> bool { matches!(vm.get_object(p), Object::Class(_)) }

Type guard

fn as_class<'a>(vm: &'a BexVm, p: HeapPtr) -> Option<&'a Class> {
    match vm.get_object(p) { Object::Class(c) => Some(c), _ => None }
}

Prevention

When it happens

Trigger: Calling `package_class_type` (directly or via `get_class`/`classes`) when a package's class slot holds a moved/stale/dropped heap pointer whose memory now holds a different object variant — typically after a GC forwarding bug or manual pointer manipulation.

Common situations: GC bugs that forward class pointers incorrectly; tests that read class pointers after sweeping without following forwarding entries; heap corruption from unsafe code that writes non-class objects into the package tables.

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


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