microsoft/semantic-kernel · error · ValueError
No serializers found for type {t}.
Error message
No serializers found for type {t}. What it means
Raised when a RoutedAgent is registered. _handles_types() discovers each handler's target_types and calls try_get_known_serializers_for_type(t), which only knows three families: Pydantic BaseModel, dataclass, and protobuf Message subclasses. If a handler declares a target type outside those families, no serializer is found and ValueError is raised, blocking registration.
Source
Thrown at python/semantic_kernel/agents/runtime/core/routed_agent.py:524
if callable(getattr(cls, attr, None)):
# Since we are getting it from the class, self is not bound
handler = getattr(cls, attr)
if hasattr(handler, "is_message_handler"):
handlers.append(cast(MessageHandler[Any, Any, Any], handler))
return handlers
@classmethod
def _handles_types(cls) -> list[tuple[type[Any], list[MessageSerializer[Any]]]]:
# TODO(evmattso): handle deduplication
handlers = cls._discover_handlers()
types: list[tuple[type[Any], list[MessageSerializer[Any]]]] = []
types.extend(cls.internal_extra_handles_types)
for handler in handlers:
for t in handler.target_types:
# TODO(evmattso): support different serializers
serializers = try_get_known_serializers_for_type(t)
if len(serializers) == 0:
raise ValueError(f"No serializers found for type {t}.")
types.append((t, try_get_known_serializers_for_type(t)))
return types
# endregion
View on GitHub (pinned to c028a0c7dc)
Solutions
- Make the message type a Pydantic BaseModel, a dataclass, or a protobuf Message subclass.
- Or register a custom MessageSerializer and add it to the registry / the agent's internal_extra_handles_types.
- If using inheritance, ensure the concrete declared type is itself one of the three supported families.
Example fix
// before
class MyMessage: # plain class -> no serializer
...
@rpc
async def handle(self, message: MyMessage, ctx: MessageContext) -> None: ...
// after
from pydantic import BaseModel
class MyMessage(BaseModel):
...
@rpc
async def handle(self, message: MyMessage, ctx: MessageContext) -> None: ... Defensive patterns
Strategy: validation
Validate before calling
import dataclasses
from pydantic import BaseModel
from google.protobuf.message import Message
from semantic_kernel.agents.runtime.core.serialization import try_get_known_serializers_for_type
def has_serializer(t: type) -> bool:
return len(try_get_known_serializers_for_type(t)) > 0 Type guard
def is_serializable_message(t: type) -> bool:
return isinstance(t, type) and (
issubclass(t, BaseModel) or dataclasses.is_dataclass(t) or issubclass(t, Message)
) Prevention
- Make every message type a Pydantic model, dataclass, or protobuf Message.
- Register custom serializers for any type outside the three supported families.
- Call try_get_known_serializers_for_type in tests before registering an agent.
When it happens
Trigger: An @rpc/@event/@message_handler whose 'message' annotation is a plain class, TypedDict, namedtuple, Enum, primitive (int/str), or any non-{BaseModel, dataclass, protobuf} type, and the agent is then registered with the runtime (which triggers _handles_types).
Common situations: Using a TypedDict or a vanilla class as a message; using an Enum or a primitive; forgetting to make the message a dataclass/pydantic model; using a third-party non-serializable type.
Related errors
- Unable to create agent
- No file found in the response.
- Unable to restore channel: invalid state.
- AzureAI project client not found.
- The Bedrock agent requires a message to be invoked.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/fbee4c870c93ac0b.
Report an issue: GitHub.