{"record":{"id":"6073b378d7f7ddcb","repo":"microsoft/autogen","slug":"dataclass-has-nested-dataclasses-or-base-models-w","errorCode":null,"errorMessage":"Dataclass has nested dataclasses or base models, which are not supported. To use nested types, use a Pydantic model","messagePattern":"Dataclass has nested dataclasses or base models, which are not supported\\. To use nested types, use a Pydantic model","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-core/src/autogen_core/_serialization.py","lineNumber":108,"sourceCode":"\n\nDataclassT = TypeVar(\"DataclassT\", bound=IsDataclass)\n\nJSON_DATA_CONTENT_TYPE = \"application/json\"\n\"\"\"JSON data content type\"\"\"\n\n# TODO: 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\nclass DataclassJsonMessageSerializer(MessageSerializer[DataclassT]):\n    def __init__(self, cls: type[DataclassT]) -> None:\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, use a Pydantic model\"\n            )\n\n        self.cls = cls\n\n    @property\n    def data_content_type(self) -> str:\n        return JSON_DATA_CONTENT_TYPE\n\n    @property\n    def type_name(self) -> str:\n        return _type_name(self.cls)\n\n    def deserialize(self, payload: bytes) -> DataclassT:\n        message_str = payload.decode(\"utf-8\")\n        return self.cls(**json.loads(message_str))\n\n    def serialize(self, message: DataclassT) -> bytes:","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/_serialization.py#L90-L126","documentation":"DataclassJsonMessageSerializer rejects dataclasses that contain nested dataclass fields or nested pydantic BaseModel fields. Nested types require recursive serialization with embedded type information, which the flat dataclass JSON serializer does not implement, so its constructor raises ValueError and points to the Pydantic serializer, which handles nesting natively.","triggerScenarios":"Building DataclassJsonMessageSerializer(Outer) where Outer has a field annotated with another @dataclass class or a BaseModel subclass (including Optional[Inner] wrappers around a nested model). Registering such a message via MessageRegistry/dataclass helpers produces the same error at serializer construction.","commonSituations":"Composing message payloads out of smaller dataclasses; gradually pydantifying a codebase so a dataclass message picks up a BaseModel field; copying example messages that were written as nested structures.","solutions":["Flatten the nested types into a single dataclass with primitive fields","Convert the whole message tree to pydantic BaseModel and register PYDANTICJsonMessageSerializer (nested models supported)","Write a custom MessageSerializer for this dataclass that serializes nested fields explicitly"],"exampleFix":"# before\n@dataclass\nclass Inner:\n    x: int\n@dataclass\nclass Outer:\n    inner: Inner\n\n# after\nclass Inner(BaseModel):\n    x: int\nclass Outer(BaseModel):\n    inner: Inner\nruntime.add_message_serializer(PYDANTICJsonMessageSerializer(Outer))","handlingStrategy":"validation","validationCode":"import dataclasses, typing\n\ndef has_nested_types(cls) -> bool:\n    for f in dataclasses.fields(cls):\n        t = f.type\n        for arg in typing.get_args(t) or (t,):\n            if dataclasses.is_dataclass(arg) or (isinstance(arg, type) and arg.__name__ == 'BaseModel'):\n                return True\n    return False\n\nassert not has_nested_types(Outer), \"flatten or use pydantic\"","typeGuard":"def is_flat_dataclass(cls) -> bool:\n    import dataclasses, typing, pydantic\n    ok = True\n    for f in dataclasses.fields(cls):\n        for arg in typing.get_args(f.type) or (f.type,):\n            if dataclasses.is_dataclass(arg) or (isinstance(arg, type) and issubclass(arg, pydantic.BaseModel)):\n                ok = False\n    return ok","tryCatchPattern":"try:\n    runtime.add_message_serializer(DataclassJsonMessageSerializer(Msg))\nexcept ValueError as e:\n    if \"nested\" in str(e):\n        runtime.add_message_serializer(PYDANTICJsonMessageSerializer(to_pydantic(Msg)))\n    else:\n        raise","preventionTips":["Keep dataclass wire messages flat (primitives + stdlib containers)","Convert entire message trees to pydantic when composition is needed","CI test that instantiates serializers for all registered messages"],"tags":["autogen-core","serialization","dataclass","nested-types","pydantic"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}