How to Resolve "TypeError: Object of type X is not JSON serializable" in Python
JSON serialization is the process of converting Python objects into a JSON string using the json module. However, the standard library only supports a limited set of native types (dicts, lists, strings, numbers, booleans, and None). Attempting to serialize other common types, such as datetime objects, Sets, NumPy arrays, or custom classes, will raise a TypeError.
This guide explains why this error occurs and provides standard solutions for serializing complex data types.
Understanding the Error
The json.dumps() function expects data that maps directly to JSON standards. If you pass an object it doesn't recognize, it throws an error.
Supported Types: dict, list, tuple, str, int, float, bool, None.
Unsupported Types: datetime, set, complex, custom classes, NumPy arrays.
import json
data = {"unique_ids": {1, 2, 3}} # Sets are not supported
try:
# ⛔️ Incorrect: Creating JSON from a Set
print(json.dumps(data))
except TypeError as e:
print(f"Error: {e}")
Output:
Error: Object of type set is not JSON serializable
Solution 1: Serializing DateTime Objects
Dates are one of the most common causes of serialization errors. JSON has no native date type, so they are typically stored as strings (ISO 8601 format).
Using default=str
The quickest fix is to tell json.dumps to convert unknown types to their string representation.
import json
from datetime import datetime
data = {
"event": "Login",
"timestamp": datetime.now()
}
try:
# ⛔️ Incorrect: datetime objects fail by default
print(json.dumps(data))
except TypeError as e:
print(f"Error: {e}")
# ✅ Correct: Use the 'default' parameter to convert objects to strings
json_output = json.dumps(data, default=str)
print(json_output)
Output:
Error: Object of type datetime is not JSON serializable
{"event": "Login", "timestamp": "2025-12-26 18:06:48.555990"}
Using default=str is a quick hack. For more control (e.g., specific date formatting), pass a custom function to default.
Solution 2: Serializing Sets
Sets ({1, 2}) are not ordered, whereas JSON arrays [] are. To serialize a set, you simply need to convert it to a list first.
import json
users = {"id": 1, "roles": {"admin", "editor"}}
# ⛔️ Incorrect: Sets trigger TypeError
# json.dumps(users)
# ✅ Correct: Convert the set to a list explicitly
users["roles"] = list(users["roles"])
print(json.dumps(users))
Output:
{"id": 1, "roles": ["admin", "editor"]}
Solution 3: Serializing Custom Classes
Python classes are not serializable by default because json doesn't know which attributes to save or how to represent them.
Returning __dict__
Most classes store their attributes in a __dict__ attribute. You can return this dictionary to serialize the object's data.
import json
class User:
def __init__(self, name, age):
self.name = name
self.age = age
user = User("Alice", 30)
try:
# ⛔️ Incorrect: Custom classes fail
print(json.dumps(user))
except TypeError as e:
print(f"Error: {e}")
# ✅ Correct: Provide a lambda that returns the object's dictionary
json_output = json.dumps(user, default=lambda o: o.__dict__)
print(json_output)
Output:
Error: Object of type User is not JSON serializable
{"name": "Alice", "age": 30}
__dict__ does not exist on all objects (e.g., classes using __slots__ or built-in types). In those cases, you need a custom serializer function.
Solution 4: The Universal default Parameter
Instead of handling every case individually or using lambda, you can define a robust serialization function that handles multiple types (Dates, Sets, Custom Classes) in one place.
import json
from datetime import datetime
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def custom_serializer(obj):
"""JSON serializer for objects not serializable by default json code"""
if isinstance(obj, (datetime,)):
return obj.isoformat()
if isinstance(obj, set):
return list(obj)
if hasattr(obj, '__dict__'):
return obj.__dict__
# Let the base class raise the error if we can't handle it
raise TypeError(f"Type {type(obj)} not serializable")
complex_data = {
"time": datetime.now(),
"tags": {"new", "sale"},
"item": Product("Laptop", 999.99)
}
# ✅ Correct: One function handling all edge cases
print(json.dumps(complex_data, default=custom_serializer, indent=2))
Output:
{
"time": "2025-12-26T18:08:04.624217",
"tags": [
"sale",
"new"
],
"item": {
"name": "Laptop",
"price": 999.99
}
}
Conclusion
To fix JSON serialization errors in Python:
- Identify the Type: Check the error message to see which object (
datetime,set, etc.) is causing the issue. - Convert Primitives: Convert
settolistmanually if feasible. - Use
default=str: For quick logging of dates or simple objects. - Use Custom Serializers: For complex applications, define a function that checks
isinstance()and converts objects to dictionaries or strings, then pass it tojson.dumps(data, default=serializer).