actix/actix-web · error · syn::Error
invalid service definition, expected #[<method>("<path>")]
Error message
invalid service definition, expected #[<method>("<path>")] What it means
Method/route macros expect a string-literal path as the first argument. At actix-web-codegen/src/route.rs:20-27 the macro tries `input.parse::<syn::LitStr>()` for the path; if the first token is not a string literal it appends this guidance message. The form is `#[<method>("<path>")]`.
Source
Thrown at actix-web-codegen/src/route.rs:21
use actix_router::ResourceDef;
use proc_macro::TokenStream;
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{punctuated::Punctuated, Ident, LitStr, Path, Token};
use crate::input_and_compile_error;
#[derive(Debug)]
pub struct RouteArgs {
pub(crate) path: syn::LitStr,
pub(crate) options: Punctuated<syn::MetaNameValue, Token![,]>,
}
impl syn::parse::Parse for RouteArgs {
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
// path to match: "/foo"
let path = input.parse::<syn::LitStr>().map_err(|mut err| {
err.combine(syn::Error::new(
err.span(),
r#"invalid service definition, expected #[<method>("<path>")]"#,
));
err
})?;
// verify that path pattern is valid
let _ = ResourceDef::new(path.value());
// if there's no comma, assume that no options are provided
if !input.peek(Token![,]) {
return Ok(Self {
path,
options: Punctuated::new(),
});
}
View on GitHub (pinned to 937960ca67)
Solutions
- Wrap the path in double quotes: `#[get("/foo")]`.
- If you need a constant path, note that macros require literals — inline the string literal directly.
- Ensure there are no stray tokens before the path string.
Example fix
// before
#[get(foo)]
async fn handler() -> HttpResponse { ... }
// after
#[get("/foo")]
async fn handler() -> HttpResponse { ... } Defensive patterns
Strategy: validation
Validate before calling
// The path must be a string literal at the macro site. There is no runtime API. // Lint rule of thumb: the first token inside #[<method>(...)] must be "...".
Prevention
- Always quote route paths.
- Do not attempt to interpolate variables into macro path arguments.
When it happens
Trigger: Writing `#[get(foo)]` (bare ident), `#[get(/foo)]` (unquoted), or `#[get("/foo".to_string())]` (expression) instead of a quoted path string.
Common situations: Forgetting quotes, using a `const` path value, or trying to interpolate a variable into the path.
Related errors
- Multiple paths specified! There should be only one.
- The #[route(..)] macro requires at least one `method` attrib
- The #[routes] macro requires at least one `#[<method>(..)]`
- missing arguments for scope macro, expected: #[scope("/prefi
- argument to scope macro is not a string literal, expected: #
AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06).
Data as JSON: /data/errors/07d5e1fca44ea8c8.json.
Report an issue: GitHub.