{"record":{"id":"1be939ae62ef2344","repo":"reflex-dev/reflex","slug":"uploaded-file-is-not-an-uploadfile-file","errorCode":null,"errorMessage":"Uploaded file is not an UploadFile.{file}","messagePattern":"Uploaded file is not an UploadFile\\.(.+?)","errorType":"exception","errorClass":"UploadValueError","httpStatus":null,"severity":"error","filePath":"packages/reflex-components-core/src/reflex_components_core/core/_upload.py","lineNumber":626,"sourceCode":"        \"\"\"Close the parsed form data exactly once.\"\"\"\n        nonlocal form_data_closed\n        if form_data_closed:\n            return\n        form_data_closed = True\n        await form_data.close()\n\n    def _create_upload_event() -> Event:\n        \"\"\"Create an upload event using the live Starlette temp files.\n\n        Returns:\n            The upload event backed by the parsed files.\n        \"\"\"\n        extra_args = _buffered_upload_args(form_data)\n        files = form_data.getlist(\"files\")\n        file_uploads = []\n        for file in files:\n            if not isinstance(file, StarletteUploadFile):\n                raise UploadValueError(\n                    \"Uploaded file is not an UploadFile.\" + str(file)\n                )\n            file_uploads.append(_upload_file_from_starlette(file))\n\n        return Event(\n            name=handler_name,\n            payload={**extra_args, handler_upload_param[0]: file_uploads},\n        )\n\n    event: Event | None = None\n    try:\n        event = _create_upload_event()\n    finally:\n        if event is None:\n            await _close_form_data()\n\n    if event is None:\n        msg = \"Upload event was not created.\"","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/packages/reflex-components-core/src/reflex_components_core/core/_upload.py#L608-L644","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use file syntax: curl -F files=@path/to/file, and in JS append a File/Blob object","Ensure every part under 'files' has a filename attribute","Check that JS FormData appends File objects, not strings or object URLs"],"exampleFix":"// before\nformData.append('files', file.name)  // string!\n\n// after\nformData.append('files', file, file.name)  // File object","handlingStrategy":"type-guard","validationCode":"for f in form_data.getlist(\"files\"):\n    assert hasattr(f, \"file\")  # Starlette UploadFile","typeGuard":"from starlette.datastructures import UploadFile\n\ndef is_upload_files(files: list) -> bool:\n    return all(isinstance(f, UploadFile) for f in files)","tryCatchPattern":null,"preventionTips":["Use curl -F files=@file and FormData.append(field, File, filename)","Never append plain strings under the files field"],"tags":["upload","multipart","type-validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}