{"id":"ac03d9ff8296fe2f","repo":"actix/actix-web","slug":"the-routes-macro-requires-at-least-one-meth","errorCode":null,"errorMessage":"The #[routes] macro requires at least one `#[<method>(..)]` attribute.","messagePattern":"The #\\[routes\\] macro requires at least one `#\\[<method>\\(\\.\\.\\)\\]` attribute\\.","errorType":"exception","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"actix-web-codegen/src/route.rs","lineNumber":536,"sourceCode":"    for attr in std::mem::take(&mut ast.attrs) {\n        match MethodType::from_path(attr.path()) {\n            Ok(method) => methods.push((method, attr)),\n            Err(_) => ast.attrs.push(attr),\n        }\n    }\n\n    let methods = match methods\n        .into_iter()\n        .map(|(method, attr)| {\n            attr.parse_args()\n                .and_then(|args| Args::new(args, Some(method)))\n        })\n        .collect::<Result<Vec<_>, _>>()\n    {\n        Ok(methods) if methods.is_empty() => {\n            return input_and_compile_error(\n                input,\n                syn::Error::new(\n                    Span::call_site(),\n                    \"The #[routes] macro requires at least one `#[<method>(..)]` attribute.\",\n                ),\n            )\n        }\n        Ok(methods) => methods,\n        Err(err) => return input_and_compile_error(input, err),\n    };\n\n    match Route::multiple(methods, ast) {\n        Ok(route) => route.into_token_stream().into(),\n        // on macro related error, make IDEs happy; see fn docs\n        Err(err) => input_and_compile_error(input, err),\n    }\n}\n","sourceCodeStart":518,"sourceCodeEnd":552,"githubUrl":"https://github.com/actix/actix-web/blob/937960ca67f20e14ffe2a075bf6d4593502be12c/actix-web-codegen/src/route.rs#L518-L552","documentation":"The `#[routes]` macro aggregates multiple method attributes on one handler. At actix-web-codegen/src/route.rs:518-540 it scans the function's attributes for recognized method paths (`get`, `post`, ...) and errors if none are found. `#[routes]` with no inner method attribute is meaningless.","triggerScenarios":"`#[routes]` decorating a function that has no `#[get(...)]`/`#[post(...)]`/etc. attributes underneath it.","commonSituations":"Adding `#[routes]` first intending to fill in methods later, or accidentally deleting the inner method attributes.","solutions":["Add at least one method attribute under `#[routes]`, e.g. `#[get(\"/x\")]`.","If only one method/path is needed, drop `#[routes]` and use the single method macro directly."],"exampleFix":"// before\n#[routes]\nasync fn handler() -> HttpResponse { ... }\n\n// after\n#[routes]\n#[get(\"/items\")]\n#[post(\"/items\")]\nasync fn handler() -> HttpResponse { ... }","handlingStrategy":"validation","validationCode":"// Compile-time only. When using #[routes], ensure at least one inner\n// method attribute (#[get(\"...\")], #[post(\"...\")], ...) is present.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add the inner method attributes immediately when you write #[routes].","Drop #[routes] if you only need a single method/path."],"tags":["rust","actix","actix-web","macro","compile-time","routing"],"analyzedSha":"937960ca67f20e14ffe2a075bf6d4593502be12c","analyzedAt":"2026-08-06T01:15:46.978Z","schemaVersion":2}