reflex-dev/reflex · error · ValueError
rx.match should have tuples of cases and one default case as
Error message
rx.match should have tuples of cases and one default case as the last argument.
What it means
rx.match's grammar is: one or more (condition, value) tuple cases, optionally followed by a single non-tuple default. If any argument other than that trailing default is a non-tuple (bare string, number, component), the structure is ambiguous and ValueError is raised.
Source
Thrown at packages/reflex-components-core/src/reflex_components_core/core/match.py:116
ValueError: If there are multiple default cases.
"""
if not cases:
msg = "rx.match should have at least one case."
raise ValueError(msg)
if not isinstance(cases[-1], tuple):
*cases, default_return = cases
default_return = (
cls._create_case_var_with_var_data(default_return)
if not isinstance(default_return, BaseComponent)
else default_return
)
else:
default_return = None
if any(case for case in cases if not isinstance(case, tuple)):
msg = "rx.match should have tuples of cases and one default case as the last argument."
raise ValueError(msg)
if not cases:
msg = "rx.match should have at least one case."
raise ValueError(msg)
return cases, default_return
@classmethod
def _create_case_var_with_var_data(cls, case_element: Any) -> Var:
"""Convert a case element into a Var.If the case
is a Style type, we extract the var data and merge it with the
newly created Var.
Args:
case_element: The case element.
Returns:
The case element Var.View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Wrap each case in a tuple: rx.match(State.x, ('a', 'Alpha'), ('b', 'Beta'), 'other')
- Put the default (non-tuple) only as the LAST argument
- When building cases from data, emit tuples: [(pattern, value), ...]
Example fix
# before
rx.match(State.size, 'small', 'large', 'unknown')
# after
rx.match(State.size, ('small', 'S'), ('large', 'L'), 'unknown') Defensive patterns
Strategy: validation
Validate before calling
for c in cases:
assert isinstance(c, tuple) and len(c) == 2, f'bad case: {c!r}'
result = rx.match(State.x, *cases, default) Type guard
def valid_match_args(cases, default) -> bool:
return bool(cases) and all(isinstance(c, tuple) and len(c) == 2 for c in cases) and not isinstance(default, tuple) Prevention
- Write each case as (pattern, value) with parentheses
- Default goes last and only once
When it happens
Trigger: `rx.match(State.x, 'a', 'b')` (bare values, no tuples); interleaving a default before tuple cases; passing lists instead of tuples for cases.
Common situations: Assuming match works like a chain of rx.cond positional pairs; forgetting the parentheses around each case; passing a default in the middle of the argument list.
Related errors
- For cases with return types as Vars, a default case must be
- The condition must be set
- rx.match should have at least one case.
- A case tuple should have at least a match case element and a
- Match condition {condition_index} of case {case_index} canno
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/4951c15e3fcd1274.
Report an issue: GitHub.