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

Multiple paths specified! There should be only one.

Error message

Multiple paths specified! There should be only one.

What it means

This compile-time error fires when a route macro receives more than one path string argument. After parsing the first path and the comma separator, the macro checks whether the next token is a literal at line 44; if so, it assumes a second path was intended and rejects it since a route maps to exactly one resource path.

Solutions

  1. Use only one path string per route attribute
  2. To register multiple paths for the same handler, use separate `#[get("/path1")]` and `#[get("/path2")]` under a `#[routes]` macro
  3. If you intended to pass options, use the key=value syntax: `#[get("/users", name = "users_list")]`

Example fix

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

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

Strategy: type-guard

Type guard

// Compile-time error. One path per route attribute:
// #[get("/users")] — correct
// #[get("/users", "/admin")] — incorrect
// Use #[routes] with multiple method attributes for multi-path handlers.

Prevention

When it happens

Trigger: Writing `#[get("/users", "/admin")]` or `#[route("/api", "/v2")]` with two string literals separated by a comma. The macro interprets the second literal as an erroneous second path.

Common situations: Developers who try to register the same handler on multiple paths in a single attribute, or who confuse the `name`, `guard`, and `wrap` options with path arguments.

Related errors


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

Appendix: source

Thrown at actix-web-codegen/src/route.rs:45

        })?;

        // 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(),
            });
        }

        // advance past comma separator
        input.parse::<Token![,]>()?;

        // if next char is a literal, assume that it is a string and show multi-path error
        if input.cursor().literal().is_some() {
            return Err(syn::Error::new(
                Span::call_site(),
                r#"Multiple paths specified! There should be only one."#,
            ));
        }

        // zero or more options: name = "foo"
        let options = input.parse_terminated(syn::MetaNameValue::parse, Token![,])?;

        Ok(Self { path, options })
    }
}

macro_rules! standard_method_type {
    (
        $($variant:ident, $upper:ident, $lower:ident,)+
    ) => {
        #[doc(hidden)]
        #[derive(Debug, Clone, PartialEq, Eq, Hash)]

View on GitHub (pinned to 4d435abc28)