PrefectHQ/fastmcp · error · TypeError

Value for state key {key!r} is not serializable. Use set_sta

Error message

Value for state key {key!r} is not serializable. Use set_state({key!r}, value, serializable=False) to store non-serializable values. Note: non-serializable state is request-scoped and will not persist across requests.

What it means

Context.set_state() serializes values (via pydantic) before storing them in the key-value store. When pydantic raises a serialization ValueError, set_state converts it into this TypeError telling you to pass serializable=False. Non-serializable state is still allowed but is request-scoped and will not persist across requests.

Source

Thrown at fastmcp_slim/fastmcp/server/context.py:1143

        The key is automatically prefixed with the session identifier.
        """
        prefixed_key = self._make_state_key(key)
        if not serializable:
            self._request_state[prefixed_key] = value
            return
        # Clear any request-scoped shadow so the session value is visible
        self._request_state.pop(prefixed_key, None)
        try:
            await self.fastmcp._state_store.put(
                key=prefixed_key,
                value=StateValue(value=value),
                ttl=self._STATE_TTL_SECONDS,
            )
        except ValueError as e:
            # Pydantic raises PydanticSerializationError (a ValueError) and the
            # message carries "serialize". Other ValueErrors propagate unchanged.
            if "serialize" in str(e).lower():
                raise TypeError(
                    f"Value for state key {key!r} is not serializable. "
                    f"Use set_state({key!r}, value, serializable=False) to store "
                    f"non-serializable values. Note: non-serializable state is "
                    f"request-scoped and will not persist across requests."
                ) from e
            raise
        except Exception as e:
            # Import the optional storage implementation only on its error path,
            # rather than adding the key_value package to every server startup.
            from key_value.aio.errors import SerializationError

            if not isinstance(e, SerializationError):
                raise
            raise TypeError(
                f"Value for state key {key!r} is not serializable. "
                f"Use set_state({key!r}, value, serializable=False) to store "
                f"non-serializable values. Note: non-serializable state is "
                f"request-scoped and will not persist across requests."

View on GitHub (pinned to 1f02114297)

Solutions

  1. Pass serializable=False if the value only needs to live for the current request: ctx.set_state(key, value, serializable=False).
  2. Otherwise store a serializable representation (dict of primitives, JSON string) and reconstruct the object on read.
  3. For objects needing custom serialization, add a model serializer or convert to a supported type before storing.

Example fix

// before
await ctx.set_state("engine", engine)
// after
await ctx.set_state("engine", engine, serializable=False)  # request-scoped
// or persist data instead:
await ctx.set_state("engine_dsn", engine.url) 
Defensive patterns

Strategy: validation

Validate before calling

import pydantic
try:
    pydantic.TypeAdapter(Any).dump_python(value)
    serializable = True
except Exception:
    serializable = False
await ctx.set_state(key, value, serializable=not serializable and needs_request_scope)

Try / catch

try:
    await ctx.set_state(key, value)
except TypeError as e:
    if "not serializable" in str(e):
        await ctx.set_state(key, value, serializable=False)
    else:
        raise

Prevention

When it happens

Trigger: ctx.set_state(key, value) where value cannot be pydantic-serialized (e.g. an open file handle, a lock, a custom object without serialization support) and serializable is not set to False.

Common situations: Storing database connections, asyncio primitives, or dataclass instances in server state; refactoring code that previously kept such objects in module globals into Context state.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/7c44cd0a8762429b. Report an issue: GitHub.