{"id":"6399bc9de79182c4","repo":"actix/actix-web","slug":"the-route-macro-requires-at-least-one-meth","errorCode":null,"errorMessage":"The #[route(..)] macro requires at least one `method` attribute","messagePattern":"The #\\[route\\(\\.\\.\\)\\] macro requires at least one `method` attribute","errorType":"exception","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"actix-web-codegen/src/route.rs","lineNumber":359,"sourceCode":"}\n\nimpl Route {\n    pub fn new(args: RouteArgs, ast: syn::ItemFn, method: Option<MethodType>) -> syn::Result<Self> {\n        let name = ast.sig.ident.clone();\n\n        // Try and pull out the doc comments so that we can reapply them to the generated struct.\n        // Note that multi line doc comments are converted to multiple doc attributes.\n        let doc_attributes = ast\n            .attrs\n            .iter()\n            .filter(|attr| attr.path().is_ident(\"doc\"))\n            .cloned()\n            .collect();\n\n        let args = Args::new(args, method)?;\n\n        if args.methods.is_empty() {\n            return Err(syn::Error::new(\n                Span::call_site(),\n                \"The #[route(..)] macro requires at least one `method` attribute\",\n            ));\n        }\n\n        if matches!(ast.sig.output, syn::ReturnType::Default) {\n            return Err(syn::Error::new_spanned(\n                ast,\n                \"Function has no return type. Cannot be used as handler\",\n            ));\n        }\n\n        Ok(Self {\n            name,\n            args: vec![args],\n            ast,\n            doc_attributes,\n        })","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/actix/actix-web/blob/937960ca67f20e14ffe2a075bf6d4593502be12c/actix-web-codegen/src/route.rs#L341-L377","documentation":"The `#[route(\"/path\")]` macro, unlike `#[get(...)]`, carries no implicit HTTP method, so it requires at least one `method = \"...\"` option. At actix-web-codegen/src/route.rs:358-363 the macro errors if `args.methods` is empty after parsing options.","triggerScenarios":"`#[route(\"/items\")]` with no options, forgetting that `route` needs explicit methods.","commonSituations":"Confusing `#[route]` (generic, needs `method`) with `#[get]`/`#[post]` (method baked in).","solutions":["Add at least one `method = \"GET\"` (or POST/PUT/etc.) option: `#[route(\"/items\", method=\"GET\")]`.","If you only need one standard method, prefer the dedicated macro: `#[get(\"/items\")]`.","To handle multiple methods on one path, list several `method = \"...\"` options."],"exampleFix":"// before\n#[route(\"/items\")]\nasync fn handler() -> HttpResponse { ... }\n\n// after\n#[route(\"/items\", method = \"GET\")]\nasync fn handler() -> HttpResponse { ... }","handlingStrategy":"validation","validationCode":"// Compile-time only. For every #[route(\"...\")] ensure at least one\n// `method = \"...\"` option is present. Prefer #[get]/#[post]/... for single methods.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to the specific method macros (#[get], #[post], ...).","Reserve #[route] for genuinely multi-method handlers and always list methods."],"tags":["rust","actix","actix-web","macro","compile-time","routing"],"analyzedSha":"937960ca67f20e14ffe2a075bf6d4593502be12c","analyzedAt":"2026-08-06T01:15:46.978Z","schemaVersion":2}