bevyengine/bevy · error

`{type_path}` should have #[reflect(Component)] or #[reflect

Error message

`{type_path}` should have #[reflect(Component)] or #[reflect(Bundle)]

What it means

The type IS registered in the `TypeRegistry`, but its registration carries neither `ReflectComponent` nor `ReflectBundle` type data, so Bevy cannot treat it as a component to insert. Those data entries are produced by the `#[reflect(Component)]` (or `#[reflect(Bundle)]`) attribute on a `Reflect`-derived type; without them, `insert_reflect` panics at the final else-branch.

Source

Thrown at crates/bevy_ecs/src/reflect/entity_commands.rs:376

fn insert_reflect_with_registry_ref(
    entity: &mut EntityWorldMut,
    type_registry: &TypeRegistry,
    component: Box<dyn PartialReflect>,
) {
    let type_info = component
        .get_represented_type_info()
        .expect("component should represent a type.");
    let type_path = type_info.type_path();
    let Some(type_registration) = type_registry.get(type_info.type_id()) else {
        panic!("`{type_path}` should be registered in type registry via `App::register_type<{type_path}>`");
    };

    if let Some(reflect_component) = type_registration.data::<ReflectComponent>() {
        reflect_component.insert(entity, component.as_partial_reflect(), type_registry);
    } else if let Some(reflect_bundle) = type_registration.data::<ReflectBundle>() {
        reflect_bundle.insert(entity, component.as_partial_reflect(), type_registry);
    } else {
        panic!("`{type_path}` should have #[reflect(Component)] or #[reflect(Bundle)]");
    }
}

/// Helper function to remove a reflect component or bundle from a given entity
fn remove_reflect_with_registry_ref(
    entity: &mut EntityWorldMut,
    type_registry: &TypeRegistry,
    component_type_path: Cow<'static, str>,
) {
    let Some(type_registration) = type_registry.get_with_type_path(&component_type_path) else {
        return;
    };
    if let Some(reflect_component) = type_registration.data::<ReflectComponent>() {
        reflect_component.remove(entity);
    } else if let Some(reflect_bundle) = type_registration.data::<ReflectBundle>() {
        reflect_bundle.remove(entity);
    }
}

View on GitHub (pinned to 396ca72708)

Solutions

  1. Add `#[reflect(Component)]` to the component (it must also `#[derive(Component)]`) so registration includes ReflectComponent data
  2. For bundle types, add `#[reflect(Bundle)]`
  3. If you cannot edit the type, attach the data manually: `app.register_type_data::<T, ReflectComponent>()` when `T: Component`

Example fix

// before
#[derive(Component, Reflect)]
struct Mass(f32);
app.register_type::<Mass>();
entity.insert_reflect(Box::new(Mass(1.0))); // panics: no #[reflect(Component)]

// after
#[derive(Component, Reflect)]
#[reflect(Component)]
struct Mass(f32);
Defensive patterns

Strategy: validation

Validate before calling

// Verify the registration carries component data before inserting
let registry = app.world().resource::<AppTypeRegistry>().read();
let has_data = registry
    .get(TypeId::of::<MyComponent>())
    .map(|r| r.data::<ReflectComponent>().is_some())
    .unwrap_or(false);
assert!(has_data, "missing #[reflect(Component)]");

Type guard

fn has_reflect_component_data<T: Reflect + 'static>(registry: &TypeRegistry) -> bool {
    registry.get(TypeId::of::<T>())
        .map(|r| r.data::<ReflectComponent>().is_some())
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: Calling `insert_reflect` on a type that derives `Reflect` (and is registered) but omits `#[reflect(Component)]`, or on a bundle type without `#[reflect(Bundle)]`.

Common situations: Adding `Reflect` to a component for serialization and forgetting the component-specific attribute; registering a plain data type (no `Component` derive) and then trying to insert it reflectively; upgrading Bevy versions where the required attribute set changed.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/fca4163a0cc2b48a. Report an issue: GitHub.