bevyengine/bevy · error
Can only derive VariantDefaults for enums
Error message
Can only derive VariantDefaults for enums
What it means
The `VariantDefaults` derive generates a `default_<variantname>()` constructor for every variant of an enum, using each field's `Default`. At variant_defaults.rs:10 the macro does `let Data::Enum(..) = &ast.data else { panic!(..) }`, so applying it to anything that is not an enum panics at compile time.
Source
Thrown at crates/bevy_ecs/macros/src/variant_defaults.rs:11
use bevy_macro_utils::fq_std::FQDefault;
use proc_macro::TokenStream;
use quote::{format_ident, quote, ToTokens};
use syn::{parse_macro_input, Data, DeriveInput};
pub(crate) fn derive_variant_defaults(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let type_ident = &ast.ident;
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
let Data::Enum(data_enum) = &ast.data else {
panic!("Can only derive VariantDefaults for enums");
};
let mut variant_defaults = Vec::new();
for variant in &data_enum.variants {
let variant_ident = &variant.ident;
let variant_name_lower = variant_ident.to_string().to_lowercase();
let variant_default_name = format_ident!("default_{}", variant_name_lower);
match &variant.fields {
syn::Fields::Named(fields_named) => {
let fqdefault = FQDefault.into_token_stream();
let fields = fields_named.named.iter().map(|f| &f.ident);
variant_defaults.push(quote! {
#[allow(missing_docs)]
pub fn #variant_default_name() -> Self {
Self::#variant_ident {
#(#fields: #fqdefault::default(),)*
}
}View on GitHub (pinned to 396ca72708)
Solutions
- Move `#[derive(VariantDefaults)]` onto an enum type
- Delete the derive from the struct/union if per-variant defaults make no sense there
- If you want struct-wide defaults, use `#[derive(Default)]` instead
Example fix
// before
#[derive(VariantDefaults)]
struct Config {
difficulty: f32,
}
// after
#[derive(VariantDefaults, Default)]
enum Difficulty {
#[default]
Easy,
Normal,
Hard,
} Defensive patterns
Strategy: validation
Validate before calling
cargo check --workspace # panics in the derive at compile time with file/line of the item
Prevention
- Reserve VariantDefaults for enum types
- Keep derive lists per-type explicit rather than copy-pasted
- Use #[derive(Default)] for struct defaults
When it happens
Trigger: `#[derive(VariantDefaults)]` on a `struct` or on a `union`. The let-else fails immediately after parsing the DeriveInput.
Common situations: Copy-pasting a derive list from an enum onto a struct during a refactor; IDE auto-import inserting every bevy derive; renaming an enum to a struct while keeping its derives.
Related errors
- Union types are not supported yet.
- Expected a Template type path
- #[{meta}] only supports structs, not enums
- Failed to parse cargo manifest: {}
- #[{meta}] only supports structs, not unions
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/f6b37423b58b168a.
Report an issue: GitHub.