yewstack/yew · error · syn::Error
only named fields are supported
Error message
only named fields are supported
What it means
Inside #[derive(Routable)] the variant scanner (packages/yew-router-macro/src/routable_derive.rs:78) rejects tuple variants (Fields::Unnamed) with 'only named fields are supported'. Route parameters captured by a pattern like #[at("/posts/{id}")] are bound by name, so variant payloads must use named fields; unit variants are allowed for parameterless routes.
Source
Thrown at packages/yew-router-macro/src/routable_derive.rs:78
ident,
variants: data.variants,
ats,
not_found_route,
})
}
}
fn parse_variants_attributes(
variants: &Punctuated<Variant, syn::token::Comma>,
) -> syn::Result<(Option<Ident>, Vec<LitStr>)> {
let mut not_founds = vec![];
let mut ats: Vec<LitStr> = vec![];
let mut not_found_attrs = vec![];
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"),
));View on GitHub (pinned to 0e4a05472f)
Solutions
- Rewrite the variant with named fields matching the route parameter names: Post { id: u32 }
- For routes with no parameters use a unit variant (e.g. Home)
- Keep field names in sync with the {param} segments in the #[at] pattern, otherwise a separate 'route parameter ... does not have a corresponding field' error follows
Example fix
// before
#[derive(Routable, Clone)]
enum Routes {
#[at("/posts/{id}")]
Post(u32),
}
// after
#[derive(Routable, Clone)]
enum Routes {
#[at("/posts/{id}")]
Post { id: u32 },
} Defensive patterns
Strategy: validation
Validate before calling
// parameter-capturing variants must use named fields matching {param} names
// #[at("/posts/{id}")] Post { id: u32 },
// static routes: unit variants #[at("/")] Home, Type guard
// route parameters are bound by field name; ensure names line up at compile time
// #[at("/posts/{id}")] Post { id: u32 } // `{id}` must equal a field ident Prevention
- Use named fields for variants with parameters; unit variants otherwise
- Match field idents exactly to {param} segments in the #[at] string
- Run cargo check after adding each variant — the derive reports shape problems early
When it happens
Trigger: Declaring a tuple variant in the route enum, e.g. Post(u32) with #[at("/posts/{id}")] — the fields check fires before the #[at] attribute is even read.
Common situations: Writing concise enum payloads with tuple syntax by habit; converting a data model enum that used tuple variants into the route enum; following non-router enum examples.
Related errors
- expected enum, found struct
- expected enum, found union
- at attribute must be present on every variant
- 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/0934ab575183fc70.
Report an issue: GitHub.