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

  1. Move the catchall to the end: '/blog/edit/[[...slug]]'
  2. Or split into separate routes for the fixed suffixes and a catchall-only route
  3. 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

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


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/aa5e19ef09f92cf7. Report an issue: GitHub.