microsoft/semantic-kernel · error · ValueError

Dataclass has nested dataclasses or base models, which are n

Error message

Dataclass has nested dataclasses or base models, which are not supported. To use nested types, use a Pydantic model

What it means

Raised by DataclassJsonMessageSerializer.__init__ when the dataclass message has a nested dataclass or Pydantic BaseModel field (has_nested_dataclass or has_nested_base_model returns True). The dataclass JSON serializer does not support nested types, so construction is rejected; use a Pydantic model instead.

Source

Thrown at python/semantic_kernel/agents/runtime/core/serialization.py:136

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)

    def deserialize(self, payload: bytes) -> DataclassT:
        """Deserialize the payload into a dataclass message."""

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Convert the message to a Pydantic BaseModel, which supports nesting.
  2. Or flatten nested fields into the top-level dataclass.
  3. Or register a custom serializer that handles the nested structure.

Example fix

// before
from dataclasses import dataclass

@dataclass
class Inner:
    x: int

@dataclass
class Msg:
    inner: Inner  # nested dataclass -> ValueError

// after
from pydantic import BaseModel

class Inner(BaseModel):
    x: int

class Msg(BaseModel):
    inner: Inner
Defensive patterns

Strategy: validation

Validate before calling

from semantic_kernel.agents.runtime.core.serialization import has_nested_dataclass, has_nested_base_model
import dataclasses

def dataclass_flat(cls) -> bool:
    return dataclasses.is_dataclass(cls) and not (has_nested_dataclass(cls) or has_nested_base_model(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 (has_nested_dataclass(cls) or has_nested_base_model(cls))

Prevention

When it happens

Trigger: Constructing/registering a dataclass message whose field is itself a dataclass or a BaseModel (and depending on the helper, a collection of them).

Common situations: Composing messages from smaller dataclass records; embedding a Pydantic sub-model inside a dataclass message.

Related errors


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