microsoft/autogen · error · ValueError
Dataclass has a union type, which is not supported. To use a
Error message
Dataclass has a union type, which is not supported. To use a union, use a Pydantic model
What it means
DataclassJsonMessageSerializer refuses dataclasses whose fields contain union types (e.g. str | None, A | B). The dataclass-based JSON serializer does type-appending/dispatch that cannot represent a union unambiguously, so the constructor raises ValueError and directs you to Pydantic, whose serializer supports unions and nested models.
Source
Thrown at python/packages/autogen-core/src/autogen_core/_serialization.py:105
if has_nested_base_model_in_type(arg):
return True
return False
DataclassT = TypeVar("DataclassT", bound=IsDataclass)
JSON_DATA_CONTENT_TYPE = "application/json"
"""JSON data content type"""
# TODO: what's the correct content type? There seems to be some disagreement over what it should be
PROTOBUF_DATA_CONTENT_TYPE = "application/x-protobuf"
"""Protobuf data content type"""
class DataclassJsonMessageSerializer(MessageSerializer[DataclassT]):
def __init__(self, cls: type[DataclassT]) -> None:
if contains_a_union(cls):
raise ValueError("Dataclass has a union type, which is not supported. To use a union, use a Pydantic model")
if has_nested_dataclass(cls) or has_nested_base_model(cls):
raise ValueError(
"Dataclass has nested dataclasses or base models, which are not supported. To use nested types, use a Pydantic model"
)
self.cls = cls
@property
def data_content_type(self) -> str:
return JSON_DATA_CONTENT_TYPE
@property
def type_name(self) -> str:
return _type_name(self.cls)
def deserialize(self, payload: bytes) -> DataclassT:
message_str = payload.decode("utf-8")View on GitHub (pinned to 027ecf0a37)
Solutions
- Convert the message dataclass to a pydantic.BaseModel and use PYDANTICJsonMessageSerializer (or MessageRegistry with pydantic messages)
- Replace the union with a single concrete type (split into separate message classes per variant, or drop the None by using a default value)
- Register a custom MessageSerializer implementation for that specific dataclass
Example fix
# before
@dataclass
class Task:
payload: str | None = None
runtime.add_message_serializer(DataclassJsonMessageSerializer(Task))
# after
class Task(BaseModel):
payload: str | None = None
runtime.add_message_serializer(PYDANTICJsonMessageSerializer(Task)) Defensive patterns
Strategy: validation
Validate before calling
import dataclasses, typing
def dataclass_is_serializable(cls) -> bool:
if not dataclasses.is_dataclass(cls):
return True
for f in dataclasses.fields(cls):
if typing.get_args(f.type) and isinstance(f.type, typing.get_args(typing.Union[int, int])[0].__class__ if False else None):
pass
# robust check: reject unions
def has_union(t):
import typing
return (typing.get_origin(t) is typing.Union)
return not any(has_union(f.type) for f in dataclasses.fields(cls))
assert dataclass_is_serializable(MyDataclass), "use pydantic for union fields" Type guard
from pydantic import BaseModel
def is_pydantic_message(msg_cls) -> bool:
return isinstance(msg_cls, type) and issubclass(msg_cls, BaseModel) Try / catch
try:
runtime.add_message_serializer(DataclassJsonMessageSerializer(Msg))
except ValueError as e:
if "union type" in str(e):
runtime.add_message_serializer(PYDANTICJsonMessageSerializer(pydantic_version_of(Msg)))
else:
raise Prevention
- Standardize all wire messages on pydantic BaseModel from the start
- Add a unit test that constructs the serializer for every registered message type
- Ban PEP 604 unions (x | None) in dataclass message fields via lint/type-check rules
When it happens
Trigger: Constructing DataclassJsonMessageSerializer(MyDataclass) or calling runtime.add_message_serializer with it, where any field of MyDataclass (or the message type you register for publish/send) is annotated with a union type. Also triggered by message_registry APIs that wrap dataclasses in this serializer automatically.
Common situations: Migrating Protobuf/dataclass examples to richer messages with optional fields (str | None); mixing dataclass messages with pydantic-style typing; upgrading code from Optional[x] sugar to PEP 604 unions (x | None), which hits the same check.
Related errors
- Dataclass has nested dataclasses or base models, which are n
- No serializers found for type {t}.
- No serializers found for type {type}. Please provide an expl
- This component does not support dumping to config
- Failed to unpack payload into {self.cls}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/f47b47622e0c0a92.
Report an issue: GitHub.