reflex-dev/reflex · error · UploadValueError

Uploaded file is not an UploadFile.{file}

Error message

Uploaded file is not an UploadFile.{file}

What it means

The buffered upload endpoint reads form_data.getlist('files') and requires every entry to be a Starlette UploadFile. A non-file value (string, because the field was sent as text without a filename) raises UploadValueError with the offending value appended.

Source

Thrown at packages/reflex-components-core/src/reflex_components_core/core/_upload.py:626

        """Close the parsed form data exactly once."""
        nonlocal form_data_closed
        if form_data_closed:
            return
        form_data_closed = True
        await form_data.close()

    def _create_upload_event() -> Event:
        """Create an upload event using the live Starlette temp files.

        Returns:
            The upload event backed by the parsed files.
        """
        extra_args = _buffered_upload_args(form_data)
        files = form_data.getlist("files")
        file_uploads = []
        for file in files:
            if not isinstance(file, StarletteUploadFile):
                raise UploadValueError(
                    "Uploaded file is not an UploadFile." + str(file)
                )
            file_uploads.append(_upload_file_from_starlette(file))

        return Event(
            name=handler_name,
            payload={**extra_args, handler_upload_param[0]: file_uploads},
        )

    event: Event | None = None
    try:
        event = _create_upload_event()
    finally:
        if event is None:
            await _close_form_data()

    if event is None:
        msg = "Upload event was not created."

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Use file syntax: curl -F files=@path/to/file, and in JS append a File/Blob object
  2. Ensure every part under 'files' has a filename attribute
  3. Check that JS FormData appends File objects, not strings or object URLs

Example fix

// before
formData.append('files', file.name)  // string!

// after
formData.append('files', file, file.name)  // File object
Defensive patterns

Strategy: type-guard

Validate before calling

for f in form_data.getlist("files"):
    assert hasattr(f, "file")  # Starlette UploadFile

Type guard

from starlette.datastructures import UploadFile

def is_upload_files(files: list) -> bool:
    return all(isinstance(f, UploadFile) for f in files)

Prevention

When it happens

Trigger: A multipart part named 'files' that is a plain text field (no filename), so Starlette parses it as str instead of UploadFile — common with hand-built bodies or clients that append files incorrectly.

Common situations: curl -F files=sometext (missing @); FormData.append('files', 'text') instead of a File/Blob; proxies converting file parts; multiple mixed entries where one part lacks filename.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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