pypa/pip · error · TypeError
Cannot serialize {obj!r}
Error message
Cannot serialize {obj!r} What it means
Raised by msgpack's pure-Python Packer._pack as the final fallthrough when the object does not match any serializable type (None, bool, int, float, bytes, bytearray, str, memoryview, ExtType, Timestamp, list, tuple, dict, or timezone-aware datetime) AND either no default callback was provided or the default callback was already invoked once and still returned an unserializable value. This is a TypeError, meaning the input type is fundamentally unsupported.
Source
Thrown at src/pip/_vendor/msgpack/fallback.py:804
self._pack(obj[i], nest_limit - 1)
return
if check(obj, dict):
return self._pack_map_pairs(len(obj), obj.items(), nest_limit - 1)
if self._datetime and check(obj, _DateTime) and obj.tzinfo is not None:
obj = Timestamp.from_datetime(obj)
default_used = 1
continue
if not default_used and self._default is not None:
obj = self._default(obj)
default_used = 1
continue
if self._datetime and check(obj, _DateTime):
raise ValueError(f"Cannot serialize {obj!r} where tzinfo=None")
raise TypeError(f"Cannot serialize {obj!r}")
def pack(self, obj):
try:
self._pack(obj)
except:
self._buffer = BytesIO() # force reset
raise
if self._autoreset:
ret = self._buffer.getvalue()
self._buffer = BytesIO()
return ret
def pack_map_pairs(self, pairs):
self._pack_map_pairs(len(pairs), pairs)
if self._autoreset:
ret = self._buffer.getvalue()
self._buffer = BytesIO()
return retView on GitHub (pinned to f399c37189)
Solutions
- Provide a default callback to Packer(default=my_func) or packb(obj, default=my_func) that converts unsupported types to dict/list/primitives.
- Convert sets to lists and custom objects to dicts before packing.
- Use recursion-safe default handlers that handle each custom type, since default is only called once per object.
- For dataclasses, use dataclasses.asdict() before packing.
Example fix
# before
packer = msgpack.Packer()
packer.pack({1, 2, 3}) # set — raises TypeError
# after — provide a default handler
def default(obj):
if isinstance(obj, set):
return list(obj)
raise TypeError(f'Cannot serialize {obj!r}')
packer = msgpack.Packer(default=default)
packer.pack({1, 2, 3}) Defensive patterns
Strategy: try-catch
Validate before calling
import msgpack
from datetime import datetime, timezone
def default_serializer(obj):
if isinstance(obj, set):
return list(obj)
if hasattr(obj, '__dict__'):
return obj.__dict__
raise TypeError(f'Cannot serialize {type(obj).__name__}')
packer = msgpack.Packer(default=default_serializer) Type guard
MSGPACK_TYPES = (type(None), bool, int, float, bytes, bytearray, str, memoryview, list, tuple, dict)
def is_msgpack_native(obj) -> bool:
return isinstance(obj, MSGPACK_TYPES) Try / catch
try:
packed = packer.pack(obj)
except TypeError as e:
if 'Cannot serialize' in str(e):
packed = packer.pack(str(obj)) # or convert to dict
else:
raise Prevention
- Always provide a default callback when packing arbitrary objects.
- Convert custom types to dicts/lists at the data boundary.
- Use dataclasses.asdict() for dataclass instances.
- Test serialization of all object types in your data model.
When it happens
Trigger: Packing a custom class instance, set, frozenset, complex, range, or any other object not in msgpack's native type table without providing a default serializer. Also raised when the default callback returns a value that is itself unserializable.
Common situations: Serializing ORM model instances, dataclasses, or custom objects without a default function; packing a set instead of a list; nested custom objects where default only handles the top level.
Related errors
- Memoryview is too large
- Cannot serialize {obj!r} where tzinfo=None
- typecode must have int type.
- data must have bytes type
- Array is too large
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/8d3fde0275d14e82.
Report an issue: GitHub.