Skip to main content

How to Solve "TypeError: Object of type set is not JSON serializable" in Python

The TypeError: Object of type set is not JSON serializable error occurs when you try to serialize a Python set object directly using the json.dumps() method. Sets are not part of the standard JSON data types.

This guide explains why this error occurs and provides the correct solutions, including converting sets to lists, creating custom encoders, and using the simplejson library as an alternative.

Understanding the Error: JSON and Sets

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It supports basic data types like:

  • Objects (similar to Python dictionaries)
  • Arrays (similar to Python lists)
  • Strings
  • Numbers (integers and floating-point)
  • Booleans (true and false)
  • null

Sets are not directly supported in the JSON standard. Therefore, Python's built-in json module doesn't know how to serialize a set by default.

import json

my_set = {'a', 'b', 'c', 'd'}

# ⛔️ TypeError: Object of type set is not JSON serializable
# json_str = json.dumps(my_set)

The simplest and most common solution is to convert the set to a list before serialization:

import json

my_set = {'a', 'b', 'c', 'd'}

json_str = json.dumps(list(my_set)) # Convert to list before serializing

print(json_str) # Output: ["a", "c", "d", "b"] (order may vary)
print(type(json_str)) # Output: <class 'str'>
  • list(my_set): Creates a list containing all the elements of the set. Note: The order of elements in a set is arbitrary, so the order in the list might not match the order you added elements.
  • json.dumps(...): Serializes the list to a JSON array string.

This is the best approach in most situations because lists are directly supported by JSON, and it's very concise.

Solution 2: Custom JSON Encoder (for Complex Cases)

If you need more control over how sets (and potentially other custom types) are serialized, you can create a custom JSONEncoder subclass:

import json

class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj) # Convert set to list
return super().default(obj) # Fallback to default for other types


my_set = {'a', 'b', 'c', 'd'}

json_str = json.dumps(my_set, cls=SetEncoder) # Pass the encoder class
print(json_str) # Output: ["a", "b", "d", "c"] (order may vary)
  • class SetEncoder(json.JSONEncoder):: We create a subclass of json.JSONEncoder.
  • def default(self, obj):: This method is called whenever json.dumps() encounters an object it doesn't know how to serialize.
    • if isinstance(obj, set):: We check if the object is a set.
    • return list(obj): If it's a set, we convert it to a list and return it.
    • return super().default(obj): If it's not a set, we call the default method of the parent class (JSONEncoder). This handles the standard JSON types and raises a TypeError if it encounters an unsupported type. This is important for handling other non-serializable types correctly.
  • To use the custom encoder, the cls parameter is passed to the json.dumps method, setting it to our custom encoder.

Solution 3: Using simplejson (with iterable_as_array)

The simplejson library is a fast, widely-used alternative to the built-in json module. It offers an option to treat all iterables (including sets) as arrays:

# Install simplejson first: pip install simplejson
import simplejson as json # Use 'as json' for convenience

my_set = {'a', 'b', 'c', 'd'}
json_str = json.dumps(my_set, iterable_as_array=True) # Serialize set as array

print(json_str) # Output: ["a", "b", "c", "d"] (order may vary)
  • iterable_as_array=True: This tells simplejson to treat any iterable object (including sets) as if it were a list/array during serialization.
note

While this works, it's generally better to be explicit and convert your sets to lists using list(my_set) before using the standard json module. This improves code clarity and avoids relying on a specific feature of simplejson.

Using the default Argument (Less Flexible)

You can pass the list constructor to the default argument of the json.dumps() method:

import json

my_set = {'a', 'b', 'c', 'd'}

json_str = json.dumps(my_set, default=list)

print(json_str)
  • The default argument is a function that returns a serializable object.
  • This is less flexible than using a custom JSONEncoder because it requires you to create a new function every time you want to handle different classes.

Conclusion

The TypeError: Object of type set is not JSON serializable error occurs because JSON doesn't have a native set data type.

  • The best solution is to convert the set to a list before serializing it with json.dumps().
  • For more complex scenarios where you need to serialize other custom types along with sets, a custom JSONEncoder subclass gives you fine-grained control. simplejson with iterable_as_array=True provides an alternative, but explicitly converting to a list is generally preferred for clarity and compatibility.
  • Avoid using the default argument to the json.dumps function for general use cases.