bevyengine/bevy · error · syn::Error

#[key(default)] is the only key override type allowed with #

Error message

#[key(default)] is the only key override type allowed with #[specialize(all)]

What it means

When `#[derive(Specializer)]` is combined with `#[specialize(all)]`, the macro generates impls for every target using default keys only; it cannot evaluate custom per-field key expressions in that mode. A field carrying a custom `#[key(<expr>)]` therefore aborts compilation with this message at the attribute's span.

Source

Thrown at crates/bevy_render/macros/src/specializer.rs:161

        let mut use_key_field = true;
        let mut key = Key::Index(key_index);
        for attr in &field.attrs {
            match &attr.meta {
                Meta::List(MetaList { path, tokens, .. }) if path.is_ident(&KEY_ATTR_IDENT) => {
                    let owned_tokens = tokens.clone().into();
                    let Ok(parsed_key) = syn::parse::<Key>(owned_tokens) else {
                        return Err(syn::Error::new(
                            attr.span(),
                            "Invalid key override attribute",
                        ));
                    };
                    key = parsed_key;
                    if matches!(
                        (&key, &targets),
                        (Key::Custom(_), SpecializeImplTargets::All)
                    ) {
                        return Err(syn::Error::new(
                            attr.span(),
                            "#[key(default)] is the only key override type allowed with #[specialize(all)]",
                        ));
                    }
                    use_key_field = false;
                }
                _ => {}
            }
        }

        if use_key_field {
            used_count += 1;
            single_index = index;
        }

        field_info.push(FieldInfo {
            ty: field_ty,
            member: field_member,

View on GitHub (pinned to 396ca72708)

Solutions

  1. Change the custom key to `#[key(default)]`
  2. Or replace `#[specialize(all)]` with explicit targets, e.g. `#[specialize(RenderPipeline)]` or a comma-separated list, which do allow custom keys
  3. Re-check every field of the struct after changing the specialize mode

Example fix

// before
#[derive(Specializer)]
#[specialize(all)]
struct Pipe {
    #[key(PipelineKey::Forward)]
    mode: Mode,
}

// after
#[derive(Specializer)]
#[specialize(all)]
struct Pipe {
    #[key(default)]
    mode: Mode,
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: `#[specialize(all)]` on the derived type plus any field with `#[key(<expression>)]` (anything other than `#[key(default)]`).

Common situations: Switching a Specializer from explicit targets to `all` (e.g. to cover RenderPipeline and compute pipelines at once) and forgetting to relax existing custom key overrides.

Related errors


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