yewstack/yew · error · syn::Error

expected enum, found union

Error message

expected enum, found union

What it means

The #[derive(Routable)] macro (packages/yew-router-macro/src/routable_derive.rs:50) requires an enum because variants are matched one-to-one against URL patterns. Applying it to a union is rejected at the union token with 'expected enum, found union'.

Source

Thrown at packages/yew-router-macro/src/routable_derive.rs:50

    ats: Vec<LitStr>,
    variants: Punctuated<Variant, syn::token::Comma>,
    not_found_route: Option<Ident>,
}

impl Parse for Routable {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let DeriveInput { ident, data, .. } = input.parse()?;

        let data = match data {
            Data::Enum(data) => data,
            Data::Struct(s) => {
                return Err(syn::Error::new(
                    s.struct_token.span(),
                    "expected enum, found struct",
                ));
            }
            Data::Union(u) => {
                return Err(syn::Error::new(
                    u.union_token.span(),
                    "expected enum, found union",
                ));
            }
        };

        let (not_found_route, ats) = parse_variants_attributes(&data.variants)?;

        Ok(Self {
            ident,
            variants: data.variants,
            ats,
            not_found_route,
        })
    }
}

fn parse_variants_attributes(

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Replace the union with an enum; each variant becomes a route with #[at("/path")]
  2. If the union is intentional for something else, remove the Routable derive from it entirely

Example fix

// before
#[derive(Routable, Clone)]
union Routes {
    home: u32,
}

// after
#[derive(Routable, Clone)]
enum Routes {
    #[at("/")]
    Home,
}
Defensive patterns

Strategy: validation

Validate before calling

// route models must be enums; verify the item kind before deriving
// enum Routes { #[at("/")] Home }

Prevention

When it happens

Trigger: Annotating a union item with #[derive(Routable)], e.g. union Routes { a: u32, b: f32 }. Data::Union is rejected before any variant attributes are read.

Common situations: Accidental paste of the derive onto a union declaration; machine-generated code that emits a union for a 'routes' type; experimenting with the derive on unusual item kinds.

Related errors


AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22). Data as JSON: /api/errors/431e1a03e18b0bb1. Report an issue: GitHub.