bevyengine/bevy · error · syn::Error

EntityEvent can only be derived for structs.

Error message

EntityEvent can only be derived for structs.

What it means

Compile error from get_event_target_field: the DeriveInput's data is not a DataStruct (it is an enum or a union), so the pattern `let Data::Struct(...)` failed and the derive cannot locate an entity-target field. It is a shape guard raised before any field inspection.

Source

Thrown at crates/bevy_ecs/macros/src/event.rs:170

        impl #impl_generics #bevy_ecs_path::event::Event for #struct_name #type_generics #where_clause {
            type Trigger<'a> = #trigger;
        }

        impl #impl_generics #bevy_ecs_path::event::EntityEvent for #struct_name #type_generics #where_clause {
            fn event_target(&self) -> #bevy_ecs_path::entity::Entity {
                #bevy_ecs_path::entity::ContainsEntity::entity(&self.#entity_field)
            }
        }

        #set_entity_event_target_impl
    })
}

/// Returns the field with the `#[event_target]` attribute, the only field if unnamed,
/// or the field with the name "entity".
fn get_event_target_field(ast: &DeriveInput) -> Result<Member> {
    let Data::Struct(DataStruct { fields, .. }) = &ast.data else {
        return Err(syn::Error::new(
            ast.span(),
            "EntityEvent can only be derived for structs.",
        ));
    };
    match fields {
        Fields::Named(fields) => fields.named.iter().find_map(|field| {
            if field.ident.as_ref().is_some_and(|i| i == "entity") || field
                .attrs
                .iter()
                .any(|attr| attr.path().is_ident(EVENT_TARGET)) {
                    Some(Member::Named(field.ident.clone()?))
                } else {
                    None
                }
        }).ok_or(syn::Error::new(
            fields.span(),
            "EntityEvent derive expected a field name 'entity' or a field annotated with #[event_target]."
        )),

View on GitHub (pinned to 396ca72708)

Solutions

  1. Derive EntityEvent only on structs, e.g. struct Attack(Entity);
  2. Use a newtype or named struct wrapping the Entity target
  3. For enums, wrap each variant payload in a struct and derive on that
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/bevy_ecs/macros/src/event.rs:170 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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