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:
print(json.dumps(data))
except TypeError as e:
print(f"Error: {e}")Output:
Error: Object of type set is not JSON serializableSolution 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:
print(json.dumps(data))
except TypeError as e:
print(f"Error: {e}")
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"}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"}}
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:
print(json.dumps(user))
except TypeError as e:
print(f"Error: {e}")
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}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__
raise TypeError(f"Type {type(obj)} not serializable")
complex_data = {
"time": datetime.now(),
"tags": {"new", "sale"},
"item": Product("Laptop", 999.99)
}
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).