{"record":{"id":"431e1a03e18b0bb1","repo":"yewstack/yew","slug":"expected-enum-found-union","errorCode":null,"errorMessage":"expected enum, found union","messagePattern":"expected enum, found union","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/yew-router-macro/src/routable_derive.rs","lineNumber":50,"sourceCode":"    ats: Vec<LitStr>,\n    variants: Punctuated<Variant, syn::token::Comma>,\n    not_found_route: Option<Ident>,\n}\n\nimpl Parse for Routable {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        let DeriveInput { ident, data, .. } = input.parse()?;\n\n        let data = match data {\n            Data::Enum(data) => data,\n            Data::Struct(s) => {\n                return Err(syn::Error::new(\n                    s.struct_token.span(),\n                    \"expected enum, found struct\",\n                ));\n            }\n            Data::Union(u) => {\n                return Err(syn::Error::new(\n                    u.union_token.span(),\n                    \"expected enum, found union\",\n                ));\n            }\n        };\n\n        let (not_found_route, ats) = parse_variants_attributes(&data.variants)?;\n\n        Ok(Self {\n            ident,\n            variants: data.variants,\n            ats,\n            not_found_route,\n        })\n    }\n}\n\nfn parse_variants_attributes(","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew-router-macro/src/routable_derive.rs#L32-L68","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Replace the union with an enum; each variant becomes a route with #[at(\"/path\")]","If the union is intentional for something else, remove the Routable derive from it entirely"],"exampleFix":"// before\n#[derive(Routable, Clone)]\nunion Routes {\n    home: u32,\n}\n\n// after\n#[derive(Routable, Clone)]\nenum Routes {\n    #[at(\"/\")]\n    Home,\n}","handlingStrategy":"validation","validationCode":"// route models must be enums; verify the item kind before deriving\n// enum Routes { #[at(\"/\")] Home }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never apply Routable to unions or structs","If a linter/rustfmt moves the derive, re-check which item it landed on","Generate route enums from a single source of truth (macro or build script) to avoid hand-editing item kinds"],"tags":["rust","derive-macro","yew-router","compile-time","routing"],"backgroundTag":"derive-macro-wrong-item-type","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}