aio-libs/aiohttp · error · ValueError
Multipart field missing name.
Error message
Multipart field missing name.
What it means
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.
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 c0ef574e29)
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.
Example fix
// before
async def handler(request):
form = await request.post() # ValueError on nameless part
# after
try:
form = await request.post()
except ValueError:
raise web.HTTPBadRequest(text="multipart fields need a name") Defensive patterns
Strategy: try-catch
Type guard
def all_parts_named(multipart_reader) -> bool:
# naive: cannot check without consuming; rely on try/except
return True Try / catch
try:
form = await request.post()
except ValueError:
raise web.HTTPBadRequest(text="multipart fields need a name") Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid default charset
- To decode nested multipart you need to use custom reader
- filename must be an instance of str. Got: %s
- content_type must be an instance of str. Got: %s
- Missing 'Host' header in request.
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/1eeaeb25f28acf00.json.
Report an issue: GitHub.