aio-libs/aiohttp · error · ValueError
Multipart field missing name.
Error message
Multipart field missing name.
What it means
While parsing multipart/form-data in BaseRequest.post(), each BodyPartReader field must carry a name (from Content-Disposition: name=). If field.name is None the part is anonymous and aiohttp raises ValueError('Multipart field missing name.'), since form fields are keyed by name.
Solutions
- Catch ValueError in the handler around await request.post() and return 400.
- Validate Content-Disposition before parsing multipart.
- Use request.multipart() directly to inspect anonymous parts yourself.
Example fix
try:
data = await request.post()
except ValueError:
raise web.HTTPBadRequest(text='malformed multipart: missing field name') Defensive patterns
Strategy: try-catch
Validate before calling
reader = await request.multipart()
async for part in reader:
if getattr(part, 'name', None) is None:
raise web.HTTPBadRequest(text='multipart field missing name') Try / catch
try:
data = await request.post()
except ValueError:
raise web.HTTPBadRequest(text='malformed multipart payload') Prevention
- Catch ValueError around await request.post().
- Validate Content-Disposition: name= on every part yourself.
- Use request.multipart() directly to control parsing.
When it happens
Trigger: A multipart part whose Content-Disposition header omits the name parameter; a file part with only filename= and no name=.
Common situations: Malformed clients; custom multipart builders omitting name; buggy HTTP libraries generating parts without Content-Disposition name.
Related errors
- content_type must be an instance of str. Got
- filename must be an instance of str. Got
- Only io.IOBase, multidict and (name, file) pairs allowed…
- boundary missed for Content-Type
- boundary %r is too long (70 chars max)
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/1eeaeb25f28acf00.
Report an issue: GitHub.
Appendix: source
Thrown at aiohttp/web_request.py:749
"application/x-www-form-urlencoded",
"multipart/form-data",
):
self._post = MultiDictProxy(MultiDict())
return self._post
out: MultiDict[str | bytes | FileField] = MultiDict()
if content_type == "multipart/form-data":
multipart = await self.multipart()
max_size = self._client_max_size
size = 0
while (field := await multipart.next()) is not None:
field_ct = field.headers.get(hdrs.CONTENT_TYPE)
if isinstance(field, BodyPartReader):
if field.name is None:
raise ValueError("Multipart field missing name.")
# Note that according to RFC 7578, the Content-Type header
# is optional, even for files, so we can't assume it's
# present.
# https://tools.ietf.org/html/rfc7578#section-4.4
if field.filename:
# store file in temp file
tmp = await self._loop.run_in_executor(
None, tempfile.TemporaryFile
)
while chunk := await field.read_chunk(size=DEFAULT_CHUNK_SIZE):
async for decoded_chunk in field.decode_iter(chunk):
await self._loop.run_in_executor(
None, tmp.write, decoded_chunk
)
size += len(decoded_chunk)
if 0 < max_size < size:
await self._loop.run_in_executor(None, tmp.close)View on GitHub (pinned to d041d4d0fd)