This rule raises an issue when calling serialization or data conversion functions without specifying a fallback parameter.

In Python, this specifically applies to the pydantic_core.to_json(), and pydantic_core.to_jsonable_python() functions.

Why is this an issue?

When serializing data, encountering an unknown or custom type will cause a serialization error if no fallback handler is provided. This happens because serialization mechanisms don’t know how to convert types they haven’t been explicitly configured to handle.

Without a fallback mechanism, your application will crash at runtime when it attempts to serialize unexpected data. This is particularly problematic in production environments where:

By providing a fallback handler, you create a safety net that prevents crashes and allows your application to handle unknown types gracefully, even if the result isn’t perfect.

Exceptions

Instances of pydantic.BaseModel and its subclasses are natively serializable by pydantic-core, provided their model_config does not set arbitrary_types_allowed = True. Calling to_json or to_jsonable_python on such objects without a fallback is safe and will not raise a PydanticSerializationError.

What is the potential impact?

Without a fallback handler, the application will raise an unhandled serialization exception when attempting to serialize unknown types. This leads to:

How to fix it

Add a fallback parameter to your pydantic-core serialization calls. The fallback function receives the unknown object and should return a serializable representation. A simple approach is to convert the object to a string using str().

Code examples

Noncompliant code example

from pydantic_core import to_json

class CustomObject:
    def __init__(self, value):
        self.value = value

data = {"key": CustomObject(42)}
result = to_json(data)  # Noncompliant: raises PydanticSerializationError

Compliant solution

from pydantic_core import to_json

class CustomObject:
    def __init__(self, value):
        self.value = value

def handle_unknown(obj):
    return str(obj)

data = {"key": CustomObject(42)}
result = to_json(data, fallback=handle_unknown)

Resources

Documentation