aio-libs/aiohttp · error · TypeError
Can not serialize value type: %r headers: %r value: %r
Error message
Can not serialize value type: %r headers: %r value: %r
What it means
Raised by FormData._gen_form_data (multipart path) wrapping any exception from payload.get_payload in a TypeError. It means none of aiohttp's registered Payload subclasses could handle the value type for the given headers/content_type. The message echoes type(value), headers, and value to aid diagnosis.
Source
Thrown at aiohttp/formdata.py:143
)
def _gen_form_data(self) -> multipart.MultipartWriter:
"""Encode a list of fields using the multipart/form-data MIME format"""
for dispparams, headers, value in self._fields:
try:
if hdrs.CONTENT_TYPE in headers:
part = payload.get_payload(
value,
content_type=headers[hdrs.CONTENT_TYPE],
headers=headers,
encoding=self._charset,
)
else:
part = payload.get_payload(
value, headers=headers, encoding=self._charset
)
except Exception as exc:
raise TypeError(
"Can not serialize value type: %r\n "
"headers: %r\n value: %r" % (type(value), headers, value)
) from exc
if dispparams:
part.set_content_disposition(
"form-data", quote_fields=self._quote_fields, **dispparams
)
# FIXME cgi.FieldStorage doesn't likes body parts with
# Content-Length which were sent via chunked transfer encoding
assert part.headers is not None
part.headers.popall(hdrs.CONTENT_LENGTH, None)
self._writer.append_payload(part)
self._fields.clear()
return self._writer
View on GitHub (pinned to c0ef574e29)
Solutions
- Convert the value to a supported type (str/bytes/IOBase) before add_field.
- For JSON, pass json.dumps(obj) as a str with content_type='application/json'.
- Register a custom payload with payload.register_payload if you need a reusable adapter.
Example fix
// before
form.add_field('data', {'a': 1}, content_type='application/json')
// after
import json
form.add_field('data', json.dumps({'a': 1}), content_type='application/json') Defensive patterns
Strategy: validation
Validate before calling
import json
value = {'a': 1}
serialized = json.dumps(value) if isinstance(value, (dict, list)) else value
form.add_field('data', serialized, content_type='application/json') Type guard
import io
from aiohttp.payload import PAYLOAD_REGISTRY
def is_supported_payload_value(v) -> bool:
return isinstance(v, (str, bytes, bytearray, memoryview, io.IOBase)) Try / catch
try:
form.add_field('data', value, content_type=ct)
except TypeError:
form.add_field('data', json.dumps(value), content_type='application/json') Prevention
- Convert dicts/lists to JSON strings before adding to a form.
- Wrap file-like objects in io.BytesIO rather than passing raw objects.
- Register a custom Payload family if you need reusable serialization.
When it happens
Trigger: Appending a field whose value is an arbitrary Python object (e.g. a dict, custom class, or set) with no registered payload handler in multipart mode. Also passing a bytes-like with an unsupported content_type that bypasses defaults.
Common situations: Trying to JSON-serialize by passing a raw dict instead of json.dumps(...); passing a custom object without registering a Payload family; passing a memoryview with a content_type that has no payload adapter.
Related errors
- filename must be an instance of str. Got: %s
- content_type must be an instance of str. Got: %s
- Only io.IOBase, multidict and (name, file) pairs allowed, us
- expected str, got {value!r}
- Unable to decode.
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/69d22efdf8683a2c.json.
Report an issue: GitHub.