{"record":{"id":"e670a5aac1f40c7a","repo":"microsoft/semantic-kernel","slug":"dataclass-has-a-union-type-which-is-not-supported","errorCode":null,"errorMessage":"Dataclass has a union type, which is not supported. To use a union, use a Pydantic model","messagePattern":"Dataclass has a union type, which is not supported\\. To use a union, use a Pydantic model","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/runtime/core/serialization.py","lineNumber":133,"sourceCode":"\nDataclassT = TypeVar(\"DataclassT\", bound=IsDataclass)\n\nJSON_DATA_CONTENT_TYPE = \"application/json\"\n\"\"\"JSON data content type\"\"\"\n\n# TODO(evmattso): what's the correct content type? There seems to be some disagreement over what it should be\nPROTOBUF_DATA_CONTENT_TYPE = \"application/x-protobuf\"\n\"\"\"Protobuf data content type\"\"\"\n\n\n@experimental\nclass DataclassJsonMessageSerializer(MessageSerializer[DataclassT]):\n    \"\"\"Serializer for dataclass messages.\"\"\"\n\n    def __init__(self, cls: type[DataclassT]) -> None:\n        \"\"\"Initialize the serializer with a dataclass type.\"\"\"\n        if contains_a_union(cls):\n            raise ValueError(\"Dataclass has a union type, which is not supported. To use a union, use a Pydantic model\")\n\n        if has_nested_dataclass(cls) or has_nested_base_model(cls):\n            raise ValueError(\n                \"Dataclass has nested dataclasses or base models, which are not supported. To use nested types, \"\n                \"use a Pydantic model\"\n            )\n\n        self.cls = cls\n\n    @property\n    def data_content_type(self) -> str:\n        \"\"\"Return the data content type.\"\"\"\n        return JSON_DATA_CONTENT_TYPE\n\n    @property\n    def type_name(self) -> str:\n        \"\"\"Return the type name.\"\"\"\n        return _type_name(self.cls)","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/runtime/core/serialization.py#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"Adding an optional or polymorphic field to a dataclass message; migrating a Pydantic model to a dataclass without removing unions.","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."],"exampleFix":"// before\nfrom dataclasses import dataclass\nfrom typing import Optional\n\n@dataclass\nclass Msg:\n    value: Optional[int]  # Union -> ValueError\n\n// after\nfrom pydantic import BaseModel\n\nclass Msg(BaseModel):\n    value: int | None","handlingStrategy":"validation","validationCode":"from semantic_kernel.agents.runtime.core.serialization import contains_a_union\nimport dataclasses\n\ndef dataclass_ok(cls) -> bool:\n    return dataclasses.is_dataclass(cls) and not contains_a_union(cls)","typeGuard":"def is_pydantic_or_flat_dataclass(cls) -> bool:\n    from pydantic import BaseModel\n    import dataclasses\n    if isinstance(cls, type) and issubclass(cls, BaseModel):\n        return True\n    return dataclasses.is_dataclass(cls) and not contains_a_union(cls)","tryCatchPattern":null,"preventionTips":["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."],"tags":["serialization","dataclass","union","pydantic"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}