reflex-dev/reflex · error · ValueError
Catchall pattern `{part}` must be at the end of the route.
Error message
Catchall pattern `{part}` must be at the end of the route. What it means
A catchall route segment ([[...slug]]) matches arbitrary trailing path segments, so Reflex requires it to be the final part of the route. verify_route_validity raises this ValueError when the catchall appears anywhere except the last position.
Source
Thrown at reflex/route.py:37
ValueError: If the route is invalid.
"""
route_parts = route.removeprefix("/").split("/")
for i, part in enumerate(route_parts):
if constants.RouteRegex.SLUG.fullmatch(part):
continue
if not part.startswith("[") or not part.endswith("]"):
msg = (
f"Route part `{part}` is not valid. Reflex only supports "
"alphabetic characters, underscores, and hyphens in route parts. "
)
raise ValueError(msg)
if part.startswith(("[[...", "[...")):
if part != constants.RouteRegex.SPLAT_CATCHALL:
msg = f"Catchall pattern `{part}` is not valid. Only `{constants.RouteRegex.SPLAT_CATCHALL}` is allowed."
raise ValueError(msg)
if i != len(route_parts) - 1:
msg = f"Catchall pattern `{part}` must be at the end of the route."
raise ValueError(msg)
continue
if part.startswith("[["):
if constants.RouteRegex.OPTIONAL_ARG.fullmatch(part):
continue
msg = (
f"Route part `{part}` with optional argument is not valid. "
"Reflex only supports optional arguments that start with an alphabetic character or underscore, "
"followed by alphanumeric characters or underscores."
)
raise ValueError(msg)
if not constants.RouteRegex.ARG.fullmatch(part):
msg = (
f"Route part `{part}` with argument is not valid. "
"Reflex only supports argument names that start with an alphabetic character or underscore, "
"followed by alphanumeric characters or underscores."
)
raise ValueError(msg)
View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Move the catchall to the end: '/blog/edit/[[...slug]]'
- Or split into separate routes for the fixed suffixes and a catchall-only route
- Handle suffix logic inside the page by parsing the slug list from route args
Example fix
# before app.add_page(page, route='/blog/[[...slug]]/edit') # after app.add_page(page, route='/blog/[[...slug]]')
Defensive patterns
Strategy: validation
Validate before calling
def validate_route(route: str):
parts = [p for p in route.strip('/').split('/') if p]
for i, p in enumerate(parts[:-1]):
if p.startswith(('[[...', '[...')):
raise ValueError('catchall must be last') Prevention
- Treat the catchall as a terminal wildcard only
- Design fixed prefixes before the catchall, never after
When it happens
Trigger: Routes like '/blog/[[...slug]]/edit' or '/api/[[...slug]]/detail' where segments follow the catchall.
Common situations: Designing nested dynamic routes and assuming catchall works like a prefix wildcard; porting Express '*' middleware style routes.
Related errors
- Catchall pattern `{part}` is not valid. Only `{constants.Rou
- Route part `{part}` is not valid. Reflex only supports alpha
- Route part `{part}` with optional argument is not valid. Ref
- Route part `{part}` with argument is not valid. Reflex only
- Arg name `{arg_name}` is used more than once in the route `{
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/aa5e19ef09f92cf7.
Report an issue: GitHub.