reflex-dev/reflex · error · ValueError

Route part `{part}` is not valid. Reflex only supports alpha

Error message

Route part `{part}` is not valid. Reflex only supports alphabetic characters, underscores, and hyphens in route parts. 

What it means

Reflex validates dynamic route segments; any part wrapped in brackets that is not an accepted pattern is rejected. A part starting with '[' but not ending with ']', or malformed bracket usage, triggers this message, which lists the allowed characters (alphabetic, underscores, hyphens) for static parts. Raised from reflex.route.verify_route_validity, called when adding a page via app.add_page.

Source

Thrown at reflex/route.py:30

def verify_route_validity(route: str) -> None:
    """Verify if the route is valid, and throw an error if not.

    Args:
        route: The route that need to be checked

    Raises:
        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):

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Use bracket syntax for dynamic args: /user/[id]
  2. For optional args use double brackets: /user/[[id]]
  3. For static parts use only letters, underscores, hyphens — no brackets
  4. For catchall use exactly /[[...slug]] at the end of the route

Example fix

# before
app.add_page(index, route='/user/<id>')

# after
app.add_page(index, route='/user/[id]')
Defensive patterns

Strategy: validation

Validate before calling

import re
from reflex.route import verify_route_validity

def safe_add_page(app, component, route):
    verify_route_validity(route)
    app.add_page(component, route=route)

Try / catch

try:
    app.add_page(page, route=route)
except ValueError as e:
    raise SystemExit(f'Invalid route {route!r}: {e}') from e

Prevention

When it happens

Trigger: Calling app.add_page(component, route='/user/[id') with an unclosed bracket, or route='/[123]' style segments that fail later regex checks, or a static segment containing invalid characters that got wrapped in brackets.

Common situations: Migrating Next.js/Flask style routes ('/user/<id>', '/user/:id') to Reflex's bracket syntax; typos in dynamic route definitions; leftover brackets in generated route strings.

Related errors


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