reflex-dev/reflex · error · ValueError

Invalid event chain: {value}

Error message

Invalid event chain: {value}

What it means

EventChain.create raises this when the value is not an EventHandler, EventSpec, EventChain, list/tuple of those, or Callable — i.e. a completely unrecognizable type was supplied where an event trigger is required.

Source

Thrown at packages/reflex-base/src/reflex_base/event/__init__.py:947

                    events.append(v)
                elif isinstance(v, FunctionVar):
                    # Apply the args_spec transformations as partial arguments to the function.
                    events.append(v.partial(*parse_args_spec(args_spec)[0]))
                elif isinstance(v, Callable):
                    # Call the lambda to get the event chain.
                    events.extend(call_event_fn(v, args_spec, key=key))
                else:
                    msg = f"Invalid event: {v}"
                    raise ValueError(msg)

        # If the input is a callable, create an event chain.
        elif isinstance(value, Callable):
            events.extend(call_event_fn(value, args_spec, key=key))

        # Otherwise, raise an error.
        else:
            msg = f"Invalid event chain: {value}"
            raise ValueError(msg)

        # Add args to the event specs if necessary.
        events = [
            (e.with_args(get_handler_args(e)) if isinstance(e, EventSpec) else e)
            for e in events
        ]

        # Return the event chain.
        return cls(
            events=events,
            args_spec=args_spec,
            **event_chain_kwargs,
        )


@dataclasses.dataclass(
    init=True,
    frozen=True,

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Pass the actual event handler or a call to it: on_click=State.handle_click
  2. Wrap foreign data in a lambda that dispatches to the right handler
  3. Validate dynamic event sources before assigning them to props

Example fix

# before
rx.button('Go', on_click='handle_click')
# after
rx.button('Go', on_click=State.handle_click)
Defensive patterns

Strategy: type-guard

Validate before calling

from reflex_base.event import EventHandler, EventSpec, EventChain
from collections.abc import Callable

def ok(v) -> bool:
    return isinstance(v, (EventHandler, EventSpec, EventChain, Callable)) or (isinstance(v, (list, tuple)) and all(ok(i) for i in v))

Type guard

def is_event_spec_like(v) -> TypeGuard[object]: return callable(v) or isinstance(v, (EventHandler, EventSpec, EventChain))

Prevention

When it happens

Trigger: Passing raw values like an int, string, dict, or object to an event prop: on_click='handle_click', on_click=1, on_click={'a': State.a}.

Common situations: Passing a string handler name (a very old Reflex pattern), passing a value from untyped data (JSON config), or wiring dynamic event maps incorrectly.

Related errors


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