Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions reflex/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,15 @@ def setup_dynamic_args(cls, args: dict[str, str]):
Args:
args: a dict of args
"""
# Skip dynamic args that have already been registered by a previous route.
args = {
k: v
for k, v in args.items()
if not (
(computed_var := cls.computed_vars.get(k)) is not None
and isinstance(computed_var, DynamicRouteVar)
)
}
Comment on lines +1298 to +1306
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Silent type mismatch when same arg registered with different types

The filter skips any arg already registered as a DynamicRouteVar, regardless of the arg's type (SINGLE vs LIST). If two routes reuse the same parameter name but with different types — e.g., /users/[id] (SINGLE) and /posts/[...id] (LIST) — the first registration always wins silently, causing the wrong accessor (string vs. list) to be used for the second route.

Consider logging a warning when the incoming v (arg type) doesn't match the type that was used when the existing DynamicRouteVar was created, so developers are alerted to the mismatch rather than experiencing subtle runtime bugs:

# Skip dynamic args that have already been registered by a previous route.
args_to_skip = {}
new_args = {}
for k, v in args.items():
    existing = cls.computed_vars.get(k)
    if existing is not None and isinstance(existing, DynamicRouteVar):
        args_to_skip[k] = v
    else:
        new_args[k] = v

if args_to_skip:
    console.warn(
        f"Dynamic route args {list(args_to_skip)} are already registered and will be skipped."
    )
args = new_args

This is a low-likelihood edge case (same arg name with different types), but the silent failure mode is worth guarding against.

if not args:
return

Expand Down
Loading