microsoft/semantic-kernel · error · ValueError

No serializers found for type {msg_type!r}. Please provide a

Error message

No serializers found for type {msg_type!r}. Please provide an explicit serializer.

What it means

Raised by the @handles decorator on BaseAgent when no serializer is supplied and the runtime cannot find a built-in serializer for the given message type. The decorator auto-discovers serializers only for pydantic BaseModel, dataclasses, and Protobuf Message subclasses; any other type yields no serializer, so the agent would be unable to (de)serialize that message over the runtime.

Source

Thrown at python/semantic_kernel/agents/runtime/core/base_agent.py:56

        return cls

    return decorator


@experimental
def handles(
    msg_type: type[Any], serializer: MessageSerializer[Any] | list[MessageSerializer[Any]] | None = None
) -> Callable[[type[BaseAgentType]], type[BaseAgentType]]:
    """Decorator for associating a message type and corresponding serializer(s) with a BaseAgent or its subclass."""

    def decorator(cls: type[BaseAgentType]) -> type[BaseAgentType]:
        if serializer is None:
            serializer_list = try_get_known_serializers_for_type(msg_type)
        else:
            serializer_list = [serializer] if not isinstance(serializer, Sequence) else list(serializer)

        if not serializer_list:
            raise ValueError(f"No serializers found for type {msg_type!r}. Please provide an explicit serializer.")

        cls.internal_extra_handles_types.append((msg_type, serializer_list))
        return cls

    return decorator


@experimental
class BaseAgent(ABC, Agent):
    """Base class for all agents."""

    internal_unbound_subscriptions_list: ClassVar[list[UnboundSubscription]] = []
    """:meta private:"""
    internal_extra_handles_types: ClassVar[list[tuple[type[Any], list[MessageSerializer[Any]]]]] = []
    """:meta private:"""

    def __init_subclass__(cls, **kwargs: Any) -> None:
        """Initialize the class."""

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Pass an explicit serializer: @handles(SomeType, serializer=MySerializer()).
  2. Make SomeType a pydantic BaseModel, a @dataclass, or a protobuf Message so a known serializer is auto-discovered.
  3. Register a custom MessageSerializer in the runtime's serialization registry and reference it.
  4. Register a custom MessageSerializer in the runtime's serialization registry and reference it.

Example fix

// before
@handles(MyPlainMessage)
class MyAgent(BaseAgent):
    ...
// after
from dataclasses import dataclass

@dataclass
class MyMessage:
    text: str

@handles(MyMessage)
class MyAgent(BaseAgent):
    ...
Defensive patterns

Strategy: validation

Validate before calling

from pydantic import BaseModel
from dataclasses import is_dataclass
from google.protobuf.message import Message

def has_known_serializer(msg_type) -> bool:
    return issubclass(msg_type, BaseModel) or is_dataclass(msg_type) or issubclass(msg_type, Message)

Type guard

def is_serializable_message_type(t: object) -> bool:
    from pydantic import BaseModel
    from dataclasses import is_dataclass
    try:
        from google.protobuf.message import Message
        proto = issubclass(t, Message)
    except Exception:
        proto = False
    return (isinstance(t, type) and (issubclass(t, BaseModel) or is_dataclass(t) or proto))

Try / catch

try:
    @handles(MyMsg)
    class MyAgent(BaseAgent): ...
except ValueError as e:
    if "No serializers found" in str(e):
        from dataclasses import dataclass
        # convert MyMsg to a dataclass or pass an explicit serializer
        @handles(MyMsg, serializer=MyMsgSerializer())
        class MyAgent(BaseAgent): ...
    else:
        raise

Prevention

When it happens

Trigger: Using @handles(SomeType) where SomeType is a plain class, a TypedDict, a str/int, or any type that is not a pydantic BaseModel, a @dataclass, or a protobuf Message, and not passing an explicit serializer argument.

Common situations: Defining a message as a regular class instead of a dataclass/pydantic model; passing a Python primitive as a message type; using a typing construct (Union, Optional) as the msg_type.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/8766b835d0955736. Report an issue: GitHub.