{"id":"1eeaeb25f28acf00","repo":"aio-libs/aiohttp","slug":"multipart-field-missing-name","errorCode":null,"errorMessage":"Multipart field missing name.","messagePattern":"Multipart field missing name\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_request.py","lineNumber":749,"sourceCode":"            \"application/x-www-form-urlencoded\",\n            \"multipart/form-data\",\n        ):\n            self._post = MultiDictProxy(MultiDict())\n            return self._post\n\n        out: MultiDict[str | bytes | FileField] = MultiDict()\n\n        if content_type == \"multipart/form-data\":\n            multipart = await self.multipart()\n            max_size = self._client_max_size\n\n            size = 0\n            while (field := await multipart.next()) is not None:\n                field_ct = field.headers.get(hdrs.CONTENT_TYPE)\n\n                if isinstance(field, BodyPartReader):\n                    if field.name is None:\n                        raise ValueError(\"Multipart field missing name.\")\n\n                    # Note that according to RFC 7578, the Content-Type header\n                    # is optional, even for files, so we can't assume it's\n                    # present.\n                    # https://tools.ietf.org/html/rfc7578#section-4.4\n                    if field.filename:\n                        # store file in temp file\n                        tmp = await self._loop.run_in_executor(\n                            None, tempfile.TemporaryFile\n                        )\n                        while chunk := await field.read_chunk(size=DEFAULT_CHUNK_SIZE):\n                            async for decoded_chunk in field.decode_iter(chunk):\n                                await self._loop.run_in_executor(\n                                    None, tmp.write, decoded_chunk\n                                )\n                                size += len(decoded_chunk)\n                                if 0 < max_size < size:\n                                    await self._loop.run_in_executor(None, tmp.close)","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/web_request.py#L731-L767","documentation":"Raised as ValueError by BaseRequest.post() (aiohttp/web_request.py:749) while iterating multipart form fields: a BodyPartReader field whose Content-Disposition has no 'name' parameter. The multipart/form-data spec (RFC 7578) requires each part to declare a name; without it aiohttp cannot key the field in the returned MultiDict, so it refuses to silently produce a nameless entry.","triggerScenarios":"await request.post() on a multipart/form-data body that contains a part with Content-Disposition: form-data; filename=foo.txt (no name= attribute). Common with hand-rolled clients, some native HTTP libraries, or proxies that strip fields.","commonSituations":"Custom file-upload clients that omit name; curl commands with -F '=@file.txt' (the empty field name); legacy desktop/mobile uploaders; testing tools that build multipart bodies manually.","solutions":["Fix the client to send Content-Disposition: form-data; name=\"field\" for every part (curl -F 'field=@file.txt').","If you must tolerate nameless parts, parse with request.multipart() directly and decide how to key them yourself.","Wrap await request.post() in try/except ValueError and return HTTPBadRequest with guidance."],"exampleFix":"// before\nasync def handler(request):\n    form = await request.post()  # ValueError on nameless part\n\n# after\ntry:\n    form = await request.post()\nexcept ValueError:\n    raise web.HTTPBadRequest(text=\"multipart fields need a name\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def all_parts_named(multipart_reader) -> bool:\n    # naive: cannot check without consuming; rely on try/except\n    return True","tryCatchPattern":"try:\n    form = await request.post()\nexcept ValueError:\n    raise web.HTTPBadRequest(text=\"multipart fields need a name\")","preventionTips":["Make clients send name= on every multipart part (curl -F 'field=@file').","Pre-parse multipart with request.multipart() if you need to tolerate nameless parts.","Wrap request.post() in try/except ValueError to convert to a 400."],"tags":["request","multipart","form-data","validation"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}