yewstack/yew · error · syn::Error
at attribute must be present on every variant
Error message
at attribute must be present on every variant
What it means
Every variant of a #[derive(Routable)] enum must carry exactly one #[at("...")] attribute so the derive can register it in the generated matchit router (packages/yew-router-macro/src/routable_derive.rs:93). A variant with zero #[at] attributes fails with 'at attribute must be present on every variant'. In this implementation the #[not_found] variant is not exempt — it also needs an #[at] path.
Source
Thrown at packages/yew-router-macro/src/routable_derive.rs:93
for variant in variants.iter() {
if let Fields::Unnamed(ref field) = variant.fields {
return Err(syn::Error::new(
field.span(),
"only named fields are supported",
));
}
let attrs = &variant.attrs;
let at_attrs = attrs
.iter()
.filter(|attr| attr.path().is_ident(AT_ATTR_IDENT))
.collect::<Vec<_>>();
let attr = match at_attrs.len() {
1 => *at_attrs.first().unwrap(),
0 => {
return Err(syn::Error::new(
variant.span(),
format!("{AT_ATTR_IDENT} attribute must be present on every variant"),
));
}
_ => {
return Err(syn::Error::new_spanned(
quote! { #(#at_attrs)* },
format!("only one {AT_ATTR_IDENT} attribute must be present"),
));
}
};
let lit = attr.parse_args::<LitStr>()?;
let val = lit.value();
if val.find('#').is_some() {
return Err(syn::Error::new_spanned(
lit,View on GitHub (pinned to 0e4a05472f)
Solutions
- Add exactly one #[at("/path")] to the offending variant — the error span points at the variant itself
- For the fallback route keep #[not_found] but also add an #[at("/")] or catch-all-style path as required by this derive
- Do not duplicate #[at] on one variant; two or more triggers 'only one at attribute must be present'
Example fix
// before
#[derive(Routable, Clone)]
enum Routes {
#[at("/")]
Home,
#[not_found]
NotFound,
}
// after
#[derive(Routable, Clone)]
enum Routes {
#[at("/")]
Home,
#[at("/")]
#[not_found]
NotFound,
} Defensive patterns
Strategy: validation
Validate before calling
// every variant (including #[not_found]) needs exactly one #[at("...")]
// enum Routes {
// #[at("/")] Home,
// #[at("/")] #[not_found] NotFound,
// } Prevention
- Add the #[at] attribute in the same edit that adds the variant
- Keep exactly one #[at] per variant — duplicates are also rejected
- Remember the fallback variant is not exempt from #[at] in this derive
When it happens
Trigger: Adding a new enum variant without an #[at] attribute; marking a fallback variant only with #[not_found] and omitting #[at]; renaming the attribute (e.g. #[route]) or using #[at] without a string literal argument.
Common situations: Extending a route enum during feature work and forgetting the attribute; migrating from an older yew-router where the not-found variant did not need a path; renaming 'at' while refactoring attributes.
Related errors
- expected enum, found struct
- expected enum, found union
- only named fields are supported
- this hook takes 2 arguments but 1 argument was supplied
- this hook takes 2 arguments but 1 argument was supplied
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/e1c9e55e11121fe5.
Report an issue: GitHub.