reflex-dev/reflex · error · ValueError

{on_upload_progress} is not a valid event handler.

Error message

{on_upload_progress} is not a valid event handler.

What it means

Upload event specs accept an on_upload_progress callback that must be an EventHandler, EventSpec, or a lambda/Callable; anything else cannot be turned into a progress event chain and is rejected when the spec is compiled (as_event_spec).

Source

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

                ),
            )
        if self.on_upload_progress is not None:
            on_upload_progress = self.on_upload_progress
            if isinstance(on_upload_progress, EventHandler):
                events = [
                    call_event_handler(
                        on_upload_progress,
                        self.on_upload_progress_args_spec,
                    ),
                ]
            elif isinstance(on_upload_progress, Callable):
                # Call the lambda to get the event chain.
                events = call_event_fn(
                    on_upload_progress, self.on_upload_progress_args_spec
                )
            else:
                msg = f"{on_upload_progress} is not a valid event handler."
                raise ValueError(msg)
            if isinstance(events, Var):
                msg = f"{on_upload_progress} cannot return a var {events}."
                raise ValueError(msg)
            on_upload_progress_chain = EventChain(
                events=[*events],
                args_spec=self.on_upload_progress_args_spec,
            )
            formatted_chain = str(format.format_prop(on_upload_progress_chain))
            spec_args.append(
                (
                    Var(_js_expr="on_upload_progress"),
                    FunctionStringVar(
                        formatted_chain.strip("{}"),
                    ).to(FunctionVar, EventChain),
                ),
            )
        return EventSpec(
            handler=handler,

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Pass the bound state method reference or a lambda: on_upload_progress=State.track_progress or on_upload_progress=lambda e: State.track(e.progress)
  2. Ensure it is a real EventHandler (decorated state method), not a string or Var

Example fix

# before
rx.upload_files_chunk(on_upload_progress='track')
# after
rx.upload_files_chunk(on_upload_progress=State.track)
Defensive patterns

Strategy: type-guard

Validate before calling

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

def ok_progress(p) -> bool:
    return isinstance(p, (EventHandler, EventSpec)) or callable(p)

Type guard

def is_progress_handler(p) -> TypeGuard[object]: return isinstance(p, (EventHandler, EventSpec)) or callable(p)

Prevention

When it happens

Trigger: Passing a string, Var, or plain object to on_upload_progress= of rx.upload_files / rx.upload_files_chunk, or a non-lambda non-handler callable wrapper the framework doesn't recognize as EventHandler/EventSpec.

Common situations: Naming a method incorrectly (passing 'on_progress' string), passing an unbound method reference, or passing a Var holding a handler name from dynamic config.

Related errors


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