{"record":{"id":"5c96f1fadeba3c2c","repo":"tokio-rs/axum","slug":"missing-from-request-via","errorCode":null,"errorMessage":"missing #[from_request(via(...))]","messagePattern":"missing #\\[from_request\\(via\\(\\.\\.\\.\\)\\)\\]","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"axum-macros/src/from_request/mod.rs","lineNumber":220,"sourceCode":"                    state_from_via(&ident, via).map(State::Custom)\n                })()\n                .unwrap_or_else(|| State::Default(syn::parse_quote!(S))),\n            };\n\n            match (via.map(second), rejection) {\n                (Some(via), rejection) => impl_enum_by_extracting_all_at_once(\n                    &ident,\n                    variants,\n                    &via,\n                    rejection.map(second).as_ref(),\n                    &state,\n                    tr,\n                ),\n                (None, Some((rejection_kw, _))) => Err(syn::Error::new_spanned(\n                    rejection_kw,\n                    \"cannot use `rejection` without `via`\",\n                )),\n                (None, _) => Err(syn::Error::new(\n                    Span::call_site(),\n                    \"missing `#[from_request(via(...))]`\",\n                )),\n            }\n        }\n        _ => Err(syn::Error::new_spanned(item, \"expected `struct` or `enum`\")),\n    }\n}\n\nfn parse_single_generic_type_on_struct(\n    generics: syn::Generics,\n    fields: &syn::Fields,\n    tr: Trait,\n) -> syn::Result<Option<Ident>> {\n    if let Some(where_clause) = generics.where_clause {\n        return Err(syn::Error::new_spanned(\n            where_clause,\n            format_args!(\"#[derive({tr})] doesn't support structs with `where` clauses\"),","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/tokio-rs/axum/blob/151cd5c12325373b86daf405a6afc0a0086a6706/axum-macros/src/from_request/mod.rs#L202-L238","documentation":"Thrown by #[derive(FromRequest)] / #[derive(FromRequestParts)] when applied to an enum (from_request/mod.rs:220). The enum branch of expand requires a #[from_request(via(SomeWrapper))] container attribute, because the generated impl converts Wrapper<Self> into Self for each variant (impl_enum_by_extracting_all_at_once). The match on (via, rejection) handles: Some(via) -> OK; (None, Some(rejection_kw)) -> 'cannot use rejection without via'; (None, _) -> this 'missing #[from_request(via(...))]' error. Field-by-field extraction is only supported on structs, not enums.","triggerScenarios":"#[derive(FromRequest)] enum Extractor { ... } (or #[derive(FromRequestParts)] enum ...) with no #[from_request(via(...))] container attribute. The match falls through to (None, _) because neither via nor rejection_kw is present.","commonSituations":"Converting a struct-based extractor to an enum (e.g. a result-like enum) and forgetting that enums mandate via. Writing an enum newtype around another extractor without specifying the wrapper. Adding #[derive(FromRequest)] to an enum that previously only derived Clone.","solutions":["Add #[from_request(via(YourWrapper))] to the enum, where YourWrapper<Self>: FromRequest (e.g. a newtype wrapper, Json, Query, or a custom wrapper).","If you wanted per-field extraction, switch the item from an enum to a struct (enums only support all-at-once extraction via a wrapper).","If you also need a custom rejection type, supply both: #[from_request(via(Wrapper), rejection(MyRejection))]."],"exampleFix":"// before\n#[derive(FromRequest, Clone)]\nenum Extractor {}\n\n// after (enum requires `via`)\n#[derive(FromRequest, Clone)]\n#[from_request(via(MyWrapper))]\nenum Extractor {}\n\n// or switch to a struct if field-by-field extraction is intended","handlingStrategy":"validation","validationCode":"// Safe invocation pattern: enums MUST declare `via(...)`.\n#[derive(FromRequest, Clone)]\n#[from_request(via(MyWrapper))] // MyWrapper<Self>: FromRequest<S>\nenum Extractor {\n    A(A),\n    B(B),\n}\n\n// If you need field-by-field extraction, use a struct instead (enums do not support it):\n#[derive(FromRequest)]\nstruct Extractor { a: A, b: B }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Before adding #[derive(FromRequest)] to an enum, choose the wrapper type and add #[from_request(via(Wrapper))] in the same edit.","Remember enums only support all-at-once extraction through a wrapper; switch to a struct for per-field extraction.","If you supply rejection(...), you must also supply via(...) — rejection alone is rejected with a sibling error.","Keep a checklist item: 'enum + FromRequest => via required'."],"tags":["axum","axum-macros","from-request","derive","enum","proc-macro","compile-error"],"backgroundTag":null,"analyzedSha":"151cd5c12325373b86daf405a6afc0a0086a6706","analyzedAt":"2026-08-11T16:57:37.422Z","contentChangedAt":"2026-08-11T16:57:37.422Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}