reflex-dev/reflex · error · UploadValueError

`{handler_name}` handler should have a parameter annotated a

Error message

`{handler_name}` handler should have a parameter annotated as rx.UploadChunkIterator

What it means

A handler registered for chunked file uploads must declare exactly one parameter annotated as rx.UploadChunkIterator so the framework knows where to inject the chunk stream. Without it there is no way to deliver uploaded chunks to your code.

Source

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

    from reflex_base.utils.exceptions import UploadTypeError, UploadValueError

    handler_name = _handler_name(handler)
    if not handler.is_background:
        msg = f"@rx.event(background=True) is required for upload_files_chunk handler `{handler_name}`."
        raise UploadTypeError(msg)

    for name, annotation in handler._get_type_hints().items():
        if name == "return":
            continue
        if annotation is UploadChunkIterator:
            return name, annotation

    msg = (
        f"`{handler_name}` handler should have a parameter annotated as "
        "rx.UploadChunkIterator"
    )
    raise UploadValueError(msg)


@dataclasses.dataclass(
    init=True,
    frozen=True,
    kw_only=True,
)
class EventActionsMixin:
    """Mixin for DOM event actions.

    Attributes:
        event_actions: Whether to `preventDefault` or `stopPropagation` on the event.
    """

    event_actions: dict[str, bool | int] = dataclasses.field(default_factory=dict)

    @property
    def stop_propagation(self) -> Self:

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Add a parameter annotated rx.UploadChunkIterator to the handler, e.g. `async def h(self, files: rx.UploadChunkIterator)`
  2. Import/qualify the annotation exactly as rx.UploadChunkIterator (string annotations must resolve to it)
  3. Keep @rx.event(background=True) on the handler as well, otherwise error 80 fires first

Example fix

# before
@rx.event(background=True)
async def handle(self, files: list[rx.UploadFile]): ...
# after
@rx.event(background=True)
async def handle(self, files: rx.UploadChunkIterator):
    async for chunk in files: ...
Defensive patterns

Strategy: type-guard

Validate before calling

import typing
from reflex import UploadChunkIterator

def has_chunk_iterator_param(fn) -> bool:
    hints = typing.get_type_hints(fn)
    return any(h is UploadChunkIterator for k, h in hints.items() if k != 'return')

Type guard

def has_chunk_iterator_param(fn) -> TypeGuard[Callable]: return any(h is UploadChunkIterator for h in typing.get_type_hints(fn).values() if h is not type(None))

Prevention

When it happens

Trigger: Calling upload_files_chunk (or upload_file) with a background=True handler whose parameters use other annotations (e.g. list[UploadFile], bytes, or no annotation) and none is rx.UploadChunkIterator.

Common situations: Porting an old rx.upload(_files) handler that took list[rx.UploadFile] to the chunked API, or forgetting to annotate the new parameter when adding the handler.

Related errors


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