{"record":{"id":"37e3739ee884aa17","repo":"bevyengine/bevy","slug":"meta-only-supports-structs-not-enums","errorCode":null,"errorMessage":"#[{meta}] only supports structs, not enums","messagePattern":"#\\[(.+?)\\] only supports structs, not enums","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/bevy_macro_utils/src/shape.rs","lineNumber":13,"sourceCode":"use syn::{\n    punctuated::Punctuated, spanned::Spanned, token::Comma, Data, DataEnum, DataUnion, Error,\n    Field, Fields,\n};\n\n/// Get the fields of a data structure if that structure is a struct;\n/// otherwise, return a compile error that points to the site of the macro invocation.\n///\n/// `meta` should be the name of the macro calling this function.\npub fn get_struct_fields<'a>(data: &'a Data, meta: &str) -> Result<&'a Fields, Error> {\n    match data {\n        Data::Struct(data_struct) => Ok(&data_struct.fields),\n        Data::Enum(DataEnum { enum_token, .. }) => Err(Error::new(\n            enum_token.span(),\n            format!(\"#[{meta}] only supports structs, not enums\"),\n        )),\n        Data::Union(DataUnion { union_token, .. }) => Err(Error::new(\n            union_token.span(),\n            format!(\"#[{meta}] only supports structs, not unions\"),\n        )),\n    }\n}\n\n/// Return an error if `Fields` is not `Fields::Named`\npub fn require_named<'a>(fields: &'a Fields) -> Result<&'a Punctuated<Field, Comma>, Error> {\n    if let Fields::Named(fields) = fields {\n        Ok(&fields.named)\n    } else {\n        Err(Error::new(\n            fields.span(),\n            \"Unnamed fields are not supported here\",","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_macro_utils/src/shape.rs#L1-L31","documentation":"bevy_macro_utils::shape::get_struct_fields emits this compile error when a Bevy derive macro that only understands structs is applied to an enum. The error span points at the `enum` keyword of the offending type. It is generated by derives such as #[derive(Bundle)], #[derive(SystemParam)], #[derive(QueryData)] and #[derive(WorldQuery)], each passing its own name in `meta`.","triggerScenarios":"Writing `#[derive(Bundle)] enum MyBundle { ... }`, or an enum with #[derive(SystemParam)], #[derive(QueryData)], or the render Specializer derive. The macro calls get_struct_fields(&ast.data, meta), matches Data::Enum, and returns the syn::Error.","commonSituations":"Trying to model 'one of several component groups' as a Bundle enum; migrating a struct to an enum while leaving the derive attached; assuming Bundle behaves like Rust's enum-based state machines.","solutions":["Convert the enum into a struct (named- or tuple-fields) whose fields are the components/params you intended to group.","For Bundle specifically, model alternatives at runtime: add a discriminant Component/enum state field and optional components instead of an enum Bundle.","For SystemParam alternatives, split into multiple systems or use Option<P> params rather than an enum param."],"exampleFix":"// before\n#[derive(Bundle)]\nenum MovementBundle {\n    Run { walk: Walk, sprint: Sprint },\n    Idle { idle: Idle },\n}\n\n// after\n#[derive(Bundle)]\nstruct MovementBundle {\n    movement: Movement, // enum component carries the variant\n    walk: Option<Walk>,\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only attach struct-only derives (Bundle, SystemParam, QueryData, WorldQuery, Specializer) to `struct` items.","Model mutually-exclusive component sets as an enum Component field plus optional components, not an enum Bundle.","Let the derive's error message guide you: it points at the `enum` keyword of the offending type."],"tags":["rust","bevy","proc-macro","derive","compile-time","ecs"],"backgroundTag":"derive-macro-invalid-input","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}