{"record":{"id":"8693ca626d9c6114","repo":"tiangolo/fastapi","slug":"expected-uploadfile-received-type-input-value","errorCode":null,"errorMessage":"Expected UploadFile, received: {type(__input_value)}","messagePattern":"Expected UploadFile, received: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"fastapi/datastructures.py","lineNumber":135,"sourceCode":"\n        Any next read or write will be done from that position.\n\n        To be awaitable, compatible with async, this is run in threadpool.\n        \"\"\"\n        return await super().seek(offset)\n\n    async def close(self) -> None:\n        \"\"\"\n        Close the file.\n\n        To be awaitable, compatible with async, this is run in threadpool.\n        \"\"\"\n        return await super().close()\n\n    @classmethod\n    def _validate(cls, __input_value: Any, _: Any) -> \"UploadFile\":\n        if not isinstance(__input_value, StarletteUploadFile):\n            raise ValueError(f\"Expected UploadFile, received: {type(__input_value)}\")\n        return cast(UploadFile, __input_value)\n\n    @classmethod\n    def __get_pydantic_json_schema__(\n        cls, core_schema: Mapping[str, Any], handler: GetJsonSchemaHandler\n    ) -> dict[str, Any]:\n        return {\"type\": \"string\", \"contentMediaType\": \"application/octet-stream\"}\n\n    @classmethod\n    def __get_pydantic_core_schema__(\n        cls, source: type[Any], handler: Callable[[Any], Mapping[str, Any]]\n    ) -> Mapping[str, Any]:\n        from ._compat.v2 import with_info_plain_validator_function\n\n        return with_info_plain_validator_function(cls._validate)\n\n\nclass DefaultPlaceholder:","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/fastapi/datastructures.py#L117-L153","documentation":"ValueError raised by UploadFile._validate, the pydantic validator registered for the UploadFile type via with_info_plain_validator_function. The validator (datastructures.py:135) requires the incoming value to be an instance of starlette UploadFile; anything else (str, bytes, dict, a file path, a SpooledTemporaryFile, etc.) is rejected because FastAPI/Starlette can only wrap a real uploaded file handle. Pydantic surfaces this ValueError as a request validation error.","triggerScenarios":"Declaring a path-operation parameter as UploadFile (or Annotated[UploadFile, File()]) but the request did not send a file part — e.g. the client sent a JSON string, plain bytes, a form field, or the test/client passed a non-file object. Also triggered by directly constructing/validating an UploadFile-typed model with a non-file input.","commonSituations":"Forgetting to upload an actual file (sending the filename string instead); test code that passes bytes to an UploadFile field instead of a file-like object; a proxy/middleware that replaced the upload with its raw contents; mismatched field name between client and endpoint.","solutions":["Send the data as a real multipart file upload with the correct field name (requests files={...}, curl -F, httpx files=).","Annotate the parameter as bytes or Annotated[bytes, File()] if you want raw bytes, or as a pydantic model / Form field if the input is not a file.","In tests, open the file and pass the file object: files={'file': ('x.bin', open(path,'rb'), 'application/octet-stream')}.","Verify the request Content-Type is multipart/form-data and the field name matches the parameter name."],"exampleFix":"// before\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile):\n    return {\"filename\": file.filename}\n# client sent JSON: {\"file\": \"report.pdf\"}  -> ValueError\n\n// after\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile):\n    return {\"filename\": file.filename}\n# client sends multipart:\n#   httpx.post(url, files={\"file\": (\"report.pdf\", open(\"report.pdf\",\"rb\"))})","handlingStrategy":"type-guard","validationCode":"# Ensure a real file object is used before constructing the request\nimport os\nfrom starlette.datastructures import UploadFile\n\ndef make_files(name: str, path: str):\n    f = open(path, \"rb\")\n    assert isinstance(f, (object,)) and os.path.exists(path)\n    return {name: (os.path.basename(path), f, \"application/octet-stream\")}","typeGuard":"from starlette.datastructures import UploadFile\n\ndef is_uploadable(value) -> bool:\n    return isinstance(value, UploadFile)","tryCatchPattern":"from fastapi import HTTPException\nfrom starlette.datastructures import UploadFile\n\nasync def take_file(value):\n    if not isinstance(value, UploadFile):\n        raise HTTPException(status_code=400, detail=\"a file upload is required\")\n    return await value.read()","preventionTips":["Always send file fields as multipart file parts, never as JSON strings.","Match the multipart field name to the endpoint parameter name.","In tests, open real file objects with the correct (filename, file, content_type) tuple.","Use Annotated[bytes, File()] when you want raw bytes instead of a file wrapper."],"tags":["uploadfile","file-upload","pydantic","multipart","validation","fastapi"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}