huggingface/smolagents · critical · SerializationError

Pickle data rejected: allow_pickle=False

Error message

Pickle data rejected: allow_pickle=False

What it means

Raised when deserializing a final answer whose payload is prefixed 'pickle:' (produced by an executor running with allow_pickle=True) but the deserializing side has allow_pickle=False. This is a deliberate security guard: untrusted pickle payloads can execute arbitrary code.

Source

Thrown at src/smolagents/remote_executors.py:329

        - "safe:" for JSON-safe payloads
        - "pickle:" for pickle payloads (only when allow_pickle=True)

        Args:
            encoded_value (`str`): Serialized string from FinalAnswerException.
            allow_pickle (`bool`, default `False`): Whether to allow pickle deserialization.

        Returns:
            `Any`: Deserialized Python object.

        Raises:
            SerializationError: If pickle data is rejected.
        """
        if encoded_value.startswith("safe:"):
            json_data = json.loads(encoded_value[5:])
            return SafeSerializer.from_json_safe(json_data)
        elif encoded_value.startswith("pickle:"):
            if not allow_pickle:
                raise SerializationError("Pickle data rejected: allow_pickle=False")
            return pickle.loads(base64.b64decode(encoded_value[7:]))
        else:
            raise SerializationError("Unknown final answer format: expected 'safe:' or 'pickle:' prefix")


class E2BExecutor(RemotePythonExecutor):
    """
    Remote Python code executor in an E2B sandbox.

    Args:
        additional_imports (`list[str]`): Additional Python packages to install.
        logger (`Logger`): Logger to use for output and errors.
        allow_pickle (`bool`, default `False`): Whether to allow pickle serialization for objects that cannot be safely serialized to JSON.
            - `False` (default, recommended): Only safe JSON serialization is used. Raises error if object cannot be safely serialized.
            - `True` (legacy mode): Tries safe JSON serialization first, falls back to pickle with warning if needed.

            **Security Warning:** Pickle deserialization can execute arbitrary code. Only set `allow_pickle=True`
            if you fully trust the execution environment and need backward compatibility with custom types.

View on GitHub (pinned to 30bb116109)

Solutions

  1. Align both sides: pass allow_pickle=True to the executor/deserializer if you trust the code producing the payload
  2. Prefer safe mode everywhere (allow_pickle=False) and make executed code return JSON-safe types
  3. Never enable pickle for untrusted or user-supplied code

Example fix

# before
executor = DockerExecutor(allow_pickle=False)  # remote side used pickle

# after
executor = DockerExecutor(allow_pickle=True)  # only if payload is trusted
Defensive patterns

Strategy: validation

Validate before calling

def payload_allowed(encoded: str, allow_pickle: bool) -> bool:
    if encoded.startswith("safe:"):
        return True
    return allow_pickle and encoded.startswith("pickle:")

Try / catch

from smolagents.remote_executors import SerializationError

try:
    value = RemotePythonExecutor._deserialize_final_answer(encoded, allow_pickle)
except SerializationError as e:
    if "allow_pickle" in str(e):
        raise RuntimeError("Remote side used pickle; align allow_pickle=True on both ends") from e
    raise

Prevention

When it happens

Trigger: The remote executor serialized the answer with pickle, but _deserialize_final_answer is called with allow_pickle=False — e.g. mixing executor configurations, or a tampered/forged 'pickle:' payload.

Common situations: Sender and receiver disagree on allow_pickle; upgrading smolagents where pickle was previously the default; processing untrusted sandbox output.

Related errors


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