TypeError: Object of type datetime is not JSON serializable
Python · updated 2026-11-03
Raised by json.dumps and json.dump (and by frameworks that use them) when a value is not one of the JSON-native types. The message names the type it could not handle: datetime, Decimal, UUID, set, bytes or your own class.
Traceback (most recent call last):
File "/app/export.py", line 22, in export_orders
payload = json.dumps({"orders": rows})
File "/usr/lib/python3.12/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
...
TypeError: Object of type datetime is not JSON serializableQuick fix
Convert the value to a JSON type before dumping (dt.isoformat(), str(decimal), str(uuid), list(a_set)), or pass default= to json.dumps with a function that does it for every unknown type. Frameworks have their own hooks (FastAPI uses jsonable_encoder, Django has DjangoJSONEncoder).
- Read the type in the message.
- For a one-off, convert that field: created_at.isoformat().
- For many values, pass default=your_function to json.dumps (or a JSONEncoder subclass).
- Keep money as Decimal in code and convert it to a string in JSON so no precision is lost.
- In Django, use DjangoJSONEncoder; in FastAPI, return the object and let it encode, or use jsonable_encoder.
import json
from datetime import date, datetime
from decimal import Decimal
from uuid import UUID
def to_json(value):
if isinstance(value, (datetime, date)):
return value.isoformat()
if isinstance(value, (Decimal, UUID)):
return str(value)
if isinstance(value, set):
return sorted(value)
raise TypeError(f"Cannot serialize {type(value).__name__}")
payload = json.dumps({"orders": rows}, default=to_json)Why it happens
Dates and times from the database
Database drivers return datetime and date objects for timestamp columns, so dumping query rows directly fails on the first one.
Decimal money values
NUMERIC columns and Decimal arithmetic produce Decimal objects, which json does not encode by default (to avoid silently turning them into floats).
UUIDs, sets and bytes
Primary keys as UUID objects, tag sets, and binary data all need an explicit conversion before they become JSON.
Your own objects
Dataclasses, model instances and other custom classes are not encoded automatically. Use dataclasses.asdict(), model_dump() (Pydantic) or an explicit dict.
Other fixes
- Do not reach for default=str everywhere: it hides bugs by turning unexpected objects into their repr.
- For logging structured data, use a logger with a JSON formatter that already knows these types.
Same error, other wording
- TypeError: Object of type Decimal is not JSON serializable
- TypeError: Object of type UUID is not JSON serializable
- TypeError: Object of type set is not JSON serializable
Let your coding agent catch the next one
Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:
> Find the 'Object of type X is not JSON serializable' errors in production, list the types and the code that dumps them, and add one shared conversion (default= or the framework's encoder) instead of per-call fixes.
Related errors
- json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
- TypeError: unsupported operand type(s) for +: 'int' and 'str'
- KeyError: 'email'
References: Python docs: json (default and JSONEncoder), Python docs: datetime.isoformat