clockworklabs/SpacetimeDB · error
Cannot nest router at `{path}`; existing routes overlap with
Error message
Cannot nest router at `{path}`; existing routes overlap with nested path What it means
Router::nest panics when the parent router already has any handler whose path starts with the nest prefix, because merging the sub-router would produce two handlers under the same subtree. The check is deliberately strict (see the FIXME in the source): even non-conflicting sub-paths trigger it.
Source
Thrown at crates/bindings/src/http.rs:349
self.add_route(MethodOrAny::Any, path, handler)
}
/// Causes requests which start with `path` to be processed by `sub_router`.
///
/// `sub_router` will be used by stripping the leading `path` from the path of the request.
///
/// Panics if `self` already has any handlers registered on paths which start with `path`.
///
/// Panics if the `path` is [invalid](Self#paths).
pub fn nest(self, path: impl Into<String>, sub_router: Self) -> Self {
let path = path.into();
assert_valid_path(&path);
// FIXME: either this check is too restrictive, or the checks in the other methods are too lenient.
// Do we want it to be the case that the `sub_router` effectively takes ownership of the whole route below `path`,
// or just the routes it actually contains?
if self.routes.iter().any(|route| route.path.starts_with(&path)) {
panic!("Cannot nest router at `{path}`; existing routes overlap with nested path");
}
let mut merged = self;
for route in sub_router.routes {
let nested_path = join_paths(&path, &route.path);
merged = merged.add_route(route.method, nested_path, route.handler);
}
merged
}
/// Combines all of the routes in `self` and `other_router` into a single [`Router`].
///
/// Panics if any of the routes in `self` conflict with any of the routes in `other_router`.
pub fn merge(self, other_router: Self) -> Self {
let mut merged = self;
for route in other_router.routes {
merged = merged.add_route(route.method, route.path, route.handler);
}View on GitHub (pinned to 6dee26c6ef)
Solutions
- Nest first: call nest("/api", sub) before adding any top-level routes under /api.
- Move the offending parent route into the sub-router (sub.route(GET, "/health", h)) so the whole subtree has one owner.
- Nest at a prefix that does not prefix-match any existing route path.
Example fix
// before
let r = Router::new()
.route(Method::GET, "/api/health", health)
.nest("/api", api_router); // panics: /api/health starts with /api
// after: subtree owned entirely by the nested router
let api_router = api_router.route(Method::GET, "/health", health);
let r = Router::new().nest("/api", api_router); Defensive patterns
Strategy: validation
Validate before calling
let prefix = "/api";
let taken: Vec<String> = vec!["/api/health".into()]; // your registry of registered paths
assert!(!taken.iter().any(|p| p.starts_with(prefix)), "cannot nest at {prefix}"); Prevention
- Nest sub-routers before registering any routes under their prefix.
- Give each subtree exactly one owner: routes under /x live only in the router nested at /x.
- Centralize router construction in one function so ordering is reviewable.
When it happens
Trigger: Registering a route under the prefix before nesting, e.g. router.route(GET, "/api/health", h) followed by router.nest("/api", sub_router); nesting two sub-routers at overlapping prefixes such as "/api" then "/api/v2".
Common situations: Composing routers in library crates where each crate registers a few routes and one also nests; refactoring flat routes into nested sub-routers incrementally.
Related errors
- Route conflict for `{path}`
- Cannot nest router at `{path}`; existing routes overlap with
- Route conflict for `{path}`
- Route paths must start with `/`: {path}
- Route paths may contain only {}: {path}
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/c72489b0903f6ef0.
Report an issue: GitHub.