{"record":{"id":"0e3d8cfbe049ff97","repo":"microsoft/autogen","slug":"root-types-cannot-be-derived-from-each-other-roo","errorCode":null,"errorMessage":"Root types cannot be derived from each other: {rootType.Name}","messagePattern":"Root types cannot be derived from each other: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Messages.cs","lineNumber":706,"sourceCode":"                parentNode.Children.Add(currentNode);\n\n                currentNode = parentNode;\n            }\n        }\n\n        public HashSet<Type> RootTypes { get; }\n        public Dictionary<Type, TypeNode> TypeNodes { get; } = new Dictionary<Type, TypeNode>();\n\n        public TypeTree(params Type[] rootTypes)\n        {\n            this.RootTypes = new HashSet<Type>();\n            foreach (var rootType in rootTypes)\n            {\n                // Check that there are no other types that this type derives from in the root types\n                // or vice versa\n                if (this.RootTypes.Any(t => t.IsAssignableFrom(rootType) || rootType.IsAssignableFrom(t)))\n                {\n                    throw new ArgumentException($\"Root types cannot be derived from each other: {rootType.Name}\");\n                }\n\n                this.RootTypes.Add(rootType);\n\n                this.EnsureType(rootType);\n\n                foreach (var derivedType in GetDerivedTypes(rootType))\n                {\n                    this.EnsureType(derivedType);\n                }\n            }\n        }\n    }\n\n    internal static readonly TypeTree MessageTypeTree = new(typeof(AgentMessage), typeof(GroupChatEventBase));\n\n    internal sealed class MessagesTypeInfoResolver : DefaultJsonTypeInfoResolver\n    {","sourceCodeStart":688,"sourceCodeEnd":724,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/Microsoft.AutoGen/AgentChat/Abstractions/Messages.cs#L688-L724","documentation":"TypeTree, used for polymorphic serialization of the AgentMessage hierarchy, requires its root types to be mutually unrelated: no root may be assignable to or from another root (t.IsAssignableFrom(rootType) || rootType.IsAssignableFrom(t)). Violating this makes the subtype mapping ambiguous, so the constructor throws ArgumentException naming the offending rootType.","triggerScenarios":"Constructing a TypeTree with two roots where one derives from the other, e.g. TypeTree(typeof(ChatMessage), typeof(AgentEvent)) when AgentEvent derives from a common base also listed, or custom message types that inherit from each other supplied as separate roots.","commonSituations":"Extending the message hierarchy with custom base/derived pairs and registering both as roots; refactoring message types so a previously unrelated pair becomes parent/child without updating TypeTree construction; copy-pasted root lists drifting out of sync with the class hierarchy.","solutions":["Register only the most-derived (or only the base) type of each hierarchy branch as a root — never both a parent and its descendant","After refactoring the message hierarchy, re-audit the root type list with a test asserting no root is assignable to another","Use the smallest set of roots: TypeTree walks derived types itself via GetDerivedTypes"],"exampleFix":"// before\nvar tree = new TypeTree(typeof(ChatMessage), typeof(TextMessage)); // TextMessage : ChatMessage\n// after\nvar tree = new TypeTree(typeof(ChatMessage)); // derived types are discovered automatically","handlingStrategy":"validation","validationCode":"bool RootsAreUnrelated(Type[] roots) => roots.All(a => roots.Where(b => b != a).All(b => !a.IsAssignableFrom(b) && !b.IsAssignableFrom(a)));\nif (!RootsAreUnrelated(roots)) throw new ArgumentException(\"TypeTree roots must not derive from each other\");\nvar tree = new TypeTree(roots);","typeGuard":"static bool AreUnrelatedRoots(Type a, Type b) => !a.IsAssignableFrom(b) && !b.IsAssignableFrom(a);","tryCatchPattern":null,"preventionTips":["Register only one type per inheritance branch as a TypeTree root","Add a startup/test assertion that no root is assignable to another root","After hierarchy refactors, re-run the serialization test suite that exercises TypeTree construction"],"tags":["autogen","serialization","polymorphism","type-tree","validation","csharp"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}