bevyengine/bevy · error · syn::Error
Invalid key override. Must be either `default` or a valid Ru
Error message
Invalid key override. Must be either `default` or a valid Rust expression of the correct key type
What it means
Bevy's `Specializer` derive lets fields override how they contribute to a specialization key with `#[key(...)]`. The payload must be either the single lowercase identifier `default` or a syntactically valid Rust expression of the field's key type. When the payload parses as an identifier that is not `default`, or fails to parse as an expression, the derive emits this KEY_ERROR_MSG.
Source
Thrown at crates/bevy_render/macros/src/specializer.rs:80
}
const KEY_ERROR_MSG: &str = "Invalid key override. Must be either `default` or a valid Rust expression of the correct key type";
impl Parse for Key {
fn parse(input: ParseStream) -> syn::Result<Self> {
if let Ok(ident) = input.parse::<Ident>() {
if ident == KEY_DEFAULT_IDENT {
Ok(Key::Default)
} else {
Err(syn::Error::new_spanned(ident, KEY_ERROR_MSG))
}
} else {
input
.parse::<Expr>()
.map(Box::new)
.map(Key::Custom)
.map_err(|mut err| {
err.extend(syn::Error::new(err.span(), KEY_ERROR_MSG));
err
})
}
}
}
#[derive(Clone)]
struct FieldInfo {
ty: Type,
member: Member,
key: Key,
}
impl FieldInfo {
fn key_ty(&self, specialize_path: &Path, target_path: &Path) -> Option<Type> {
let ty = &self.ty;
matches!(self.key, Key::Whole | Key::Index(_))
.then_some(parse_quote!(<#ty as #specialize_path::Specializer<#target_path>>::Key))View on GitHub (pinned to 396ca72708)
Solutions
- Use the exact lowercase identifier: `#[key(default)]`
- Otherwise supply one complete, valid expression of the field's key type, e.g. `#[key(Mode::Alpha as u8)]`
- Check for stray characters, unmatched parens or duplicated tokens inside the attribute
Example fix
// before #[key(Default)] mode: Mode, // after #[key(default)] mode: Mode,
Defensive patterns
Strategy: validation
Prevention
- Use the exact identifier `default` (lowercase) in #[key(...)]
- Keep key expressions complete and compilable on one line
- Run cargo check after every key-attribute edit; these are compile-time errors
When it happens
Trigger: `#[key(Default)]` (capital D parses as an identifier that is not `default`), `#[key()]` or any leftover fragment where the expression parser also fails.
Common situations: Typing `Default` out of habit instead of `default`; leaving a half-edited expression like `#[key(Mode::A +)]` after refactoring a key enum.
Related errors
- Invalid key override attribute
- #[key(default)] is the only key override type allowed with #
- #[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/d2b32b1907983d76.
Report an issue: GitHub.