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 list[rx.UploadFile]

What it means

resolve_upload_handler_param scans the handler's type hints for exactly one parameter annotated list[rx.UploadFile] (origin list, single arg subclassing UploadFile). If no parameter matches, UploadValueError is raised telling you the required annotation. Other list[...] params and non-list annotations are skipped.

Source

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

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

    for name, annotation in handler._get_type_hints().items():
        if name == "return" or get_origin(annotation) is not list:
            continue
        args = get_args(annotation)
        if len(args) == 1 and typehint_issubclass(args[0], UploadFile):
            return name, annotation

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


def resolve_upload_chunk_handler_param(handler: "EventHandler") -> tuple[str, type]:
    """Validate and resolve the UploadChunkIterator parameter for a handler.

    Args:
        handler: The event handler to inspect.

    Returns:
        The parameter name and annotation for the iterator argument.

    Raises:
        UploadTypeError: If the handler is not a background task.
        UploadValueError: If the handler does not accept an UploadChunkIterator.
    """
    from reflex_components_core.core._upload import UploadChunkIterator

    from reflex_base.utils.exceptions import UploadTypeError, UploadValueError

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Annotate exactly one parameter as list[rx.UploadFile] even for single-file uploads
  2. Import UploadFile from reflex so the issubclass check passes
  3. Keep the parameter positional and don't wrap it in extra generics

Example fix

# before
@rx.event
def handle_upload(file: rx.UploadFile): ...
# after
@rx.event
def handle_upload(files: list[rx.UploadFile]): ...
Defensive patterns

Strategy: type-guard

Validate before calling

import typing
from reflex import UploadFile
hints = typing.get_type_hints(handler.fn)
assert any(get_origin(a) is list and get_args(a) and issubclass(get_args(a)[0], UploadFile)
           for n, a in hints.items() if n != "return"), "missing list[rx.UploadFile] param"

Type guard

def has_upload_param(handler) -> bool:
    import typing
    from reflex import UploadFile
    for n, a in typing.get_type_hints(handler.fn).items():
        if n == "return":
            continue
        if typing.get_origin(a) is list and (args := typing.get_args(a)) and issubclass(args[0], UploadFile):
            return True
    return False

Try / catch

null

Prevention

When it happens

Trigger: Defining an upload handler whose parameter is annotated rx.UploadFile (not a list), list[UploadFile]-equivalents from a different class, list[Any], or missing the parameter entirely — then using it with rx.upload_file().

Common situations: Annotating with a single UploadFile because the UI uploads one file, importing UploadFile from the wrong module so the subclass check fails, or renaming/loosening the annotation.

Related errors


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