actix/actix-web · error · syn::Error

invalid service definition, expected #

Error message

invalid service definition, expected #[<method>("<path>")]

What it means

This compile-time error fires when the first argument inside a route macro attribute (e.g., `#[get(...)]`, `#[post(...)]`) cannot be parsed as a string literal. The macro expects the form `#[<method>("<path>")]` and tries to parse the tokens as `syn::LitStr` at line 20; if the token is a number, identifier, or expression, parsing fails with this message.

Solutions

  1. Wrap the path in double quotes: `#[get("/users")]` instead of `#[get(/users)]`
  2. Do not use variables or constants as the path argument; use a string literal
  3. Ensure there are no stray characters or missing quotes in the attribute

Example fix

// before
#[get(/users)]
async fn users() -> impl Responder { ... }

// after
#[get("/users")]
async fn users() -> impl Responder { ... }
Defensive patterns

Strategy: type-guard

Type guard

// This is a compile-time error. Ensure the path is a string literal:
// #[get("/users")] — correct
// #[get(/users)]  — incorrect (missing quotes)
// cargo check will report this error with the exact location.

Prevention

When it happens

Trigger: Writing `#[get(/users)]` (path without quotes), `#[get(42)]` (non-string), or `#[get(foo)]` (bare identifier). Any route macro where the path argument is not a quoted string literal triggers this.

Common situations: Forgetting to wrap the route path in quotes, or attempting to use a constant/variable as the path. Most common when developers are used to other frameworks that accept bare paths.

Related errors


AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09). Data as JSON: /api/errors/07d5e1fca44ea8c8. Report an issue: GitHub.

Appendix: 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 4d435abc28)