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
- Use only one path string per route attribute
- To register multiple paths for the same handler, use separate `#[get("/path1")]` and `#[get("/path2")]` under a `#[routes]` macro
- 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
- Use exactly one string literal path per route attribute
- For the same handler on multiple paths, use #[routes] with separate #[get("/path1")] attributes
- Review the actix-web codegen documentation for multi-route patterns
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
- argument to scope macro is not a string literal, expected…
- invalid service definition, expected #
- missing arguments for scope macro, expected…
- #[scope] macro must be attached to a module
- scopes should not have trailing slashes; see…
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)