microsoft/semantic-kernel · 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
Raised by DataclassJsonMessageSerializer.__init__ when the dataclass message contains a Union-typed field (contains_a_union returns True). The dataclass JSON serializer cannot represent unions, so construction is rejected and the library directs you to use a Pydantic model instead. Note: Optional[X] is itself a Union, so optional fields trigger this too.
Source
Thrown at python/semantic_kernel/agents/runtime/core/serialization.py:133
DataclassT = TypeVar("DataclassT", bound=IsDataclass)
JSON_DATA_CONTENT_TYPE = "application/json"
"""JSON data content type"""
# TODO(evmattso): 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"""
@experimental
class DataclassJsonMessageSerializer(MessageSerializer[DataclassT]):
"""Serializer for dataclass messages."""
def __init__(self, cls: type[DataclassT]) -> None:
"""Initialize the serializer with a dataclass type."""
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 the data content type."""
return JSON_DATA_CONTENT_TYPE
@property
def type_name(self) -> str:
"""Return the type name."""
return _type_name(self.cls)View on GitHub (pinned to c028a0c7dc)
Solutions
- Convert the message to a Pydantic BaseModel, which supports unions natively.
- Or eliminate the union by splitting into separate non-union dataclasses.
- Avoid Optional/Union fields on dataclass messages.
Example fix
// before
from dataclasses import dataclass
from typing import Optional
@dataclass
class Msg:
value: Optional[int] # Union -> ValueError
// after
from pydantic import BaseModel
class Msg(BaseModel):
value: int | None Defensive patterns
Strategy: validation
Validate before calling
from semantic_kernel.agents.runtime.core.serialization import contains_a_union
import dataclasses
def dataclass_ok(cls) -> bool:
return dataclasses.is_dataclass(cls) and not contains_a_union(cls) Type guard
def is_pydantic_or_flat_dataclass(cls) -> bool:
from pydantic import BaseModel
import dataclasses
if isinstance(cls, type) and issubclass(cls, BaseModel):
return True
return dataclasses.is_dataclass(cls) and not contains_a_union(cls) Prevention
- Prefer Pydantic models when a message needs union/optional fields.
- Keep dataclass messages flat with concrete field types.
- Check contains_a_union before registering a dataclass message.
When it happens
Trigger: Constructing/registering a dataclass message that has a field typed as Union[A, B], A | B, or Optional[A]; any field whose annotation resolves to a Union.
Common situations: Adding an optional or polymorphic field to a dataclass message; migrating a Pydantic model to a dataclass without removing unions.
Related errors
- Dataclass has nested dataclasses or base models, which are n
- Unable to restore channel: invalid state.
- Unable to transform output to {typeof(TOutput)}.
- Unable to transform result into {typeof(TOutput).Name}
- Unexpected author role: {role}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/e670a5aac1f40c7a.
Report an issue: GitHub.