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
- Change the custom key to `#[key(default)]`
- Or replace `#[specialize(all)]` with explicit targets, e.g. `#[specialize(RenderPipeline)]` or a comma-separated list, which do allow custom keys
- 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
- Decide the specialize mode first, then pick matching key overrides
- With #[specialize(all)], audit that every #[key(...)] is exactly `default`
- Switch to explicit targets when custom keys are required
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
- Invalid key override. Must be either `default` or a valid Ru
- Invalid key override attribute
- #[derive({derive_name})] must be accompanied by #[specialize
- Union types are not supported yet.
- Expected a Template type path
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/5e62c54e4cf80dc5.
Report an issue: GitHub.