huggingface/smolagents · error · SerializationError

Cannot serialize object

Error message

Cannot serialize object: {e}

What it means

SafeSerializer.dumps tried to serialize an object that is not JSON-safe and also could not be pickled (pickle raised PicklingError, TypeError, or AttributeError). The serializer's fallback chain is: JSON-safe types, then base64-pickled bytes with a 'pickle:' prefix; when both fail it raises this SerializationError. It usually means the object holds unpicklable state such as open file handles, sockets, threads, locks, lambdas, or modules.

Solutions

  1. Find the unpicklable attribute (run pickle.dumps on suspected fields individually) and remove/replace it before serializing
  2. Convert the object to plain dict/list/str primitives (e.g. define to_dict() or __json_safe__ conversion) before passing it
  3. For resources like files/sessions, store a serializable descriptor (path, config) instead of the live object
  4. As a last resort, sanitize the object (del/None out locks, sockets) before serialization

Example fix

# before
result = {"model": my_agent.model, "session": requests.Session()}
SafeSerializer.dumps(result)  # Cannot serialize object

# after
result = {"model": str(my_agent.model), "session": None}
SafeSerializer.dumps(result)
Defensive patterns

Strategy: validation

Validate before calling

import pickle

def is_serializable(obj) -> bool:
    try:
        pickle.dumps(obj)
        return True
    except Exception:
        return False

# before dumps(): assert is_serializable(payload) or sanitize it

Type guard

def is_json_safe(v) -> bool:
    return v is None or isinstance(v, (str, int, float, bool, list, dict)) and (not isinstance(v, dict) or all(is_json_safe(x) for x in v.values())) and (not isinstance(v, list) or all(is_json_safe(x) for x in v))

Try / catch

from smolagents.serialization import SerializationError
try:
    SafeSerializer.dumps(payload)
except SerializationError:
    payload = sanitize(payload)  # replace live resources with descriptors
    SafeSerializer.dumps(payload)

Prevention

When it happens

Trigger: Calling append_answer, model_dump_json, render_as_markdown, log_messages, send_variables, or _serialize_with_fallback with an object containing non-picklable members (open files, sockets, DB connections, threading locks, lambdas, module references) after json-safe conversion already failed.

Common situations: Saving agent logs/traces where a Tool instance or action output holds a live resource (open file, requests.Session, boto3 client); lambdas stored in tool outputs; objects with __slots__ missing __getstate__; objects referencing sys.modules internals.

Related errors


AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28). Data as JSON: /api/errors/cb8232be20a29238. Report an issue: GitHub.

Appendix: source

Thrown at src/smolagents/serialization.py:292

                json_safe = SafeSerializer.to_json_safe(obj)
                return SafeSerializer.SAFE_PREFIX + json.dumps(json_safe)
            except SerializationError:
                # Warn about insecure pickle usage
                import warnings

                warnings.warn(
                    "Falling back to insecure pickle serialization. "
                    "This is a security risk and will be removed in a future version. "
                    "Consider using only safe serializable types (primitives, lists, dicts, "
                    "numpy arrays, PIL images, datetime objects, dataclasses).",
                    FutureWarning,
                    stacklevel=2,
                )
                # Fallback to pickle (with prefix)
                try:
                    return "pickle:" + base64.b64encode(pickle.dumps(obj)).decode()
                except (pickle.PicklingError, TypeError, AttributeError) as e:
                    raise SerializationError(f"Cannot serialize object: {e}") from e

    @staticmethod
    def loads(data: str, allow_pickle: bool = False) -> Any:
        """
        Deserialize string with format detection.

        Args:
            data: Serialized string (with "safe:" or "pickle:" prefix)
            allow_pickle: If False (default), reject pickle data (strict safe mode).
                         If True, accept both safe and pickle formats.

        Returns:
            Deserialized object

        Raises:
            SerializationError: If pickle data received but allow_pickle=False
        """
        if data.startswith(SafeSerializer.SAFE_PREFIX):

View on GitHub (pinned to 30bb116109)