{"record":{"id":"625944eb8f3325da","repo":"dotnet/wpf","slug":"sr-format-sr-typemustimplementiaddchild-frameworkobject-do","errorCode":null,"errorMessage":"SR.Format(SR.TypeMustImplementIAddChild, frameworkObject.DO.GetType().Name)","messagePattern":"SR\\.Format\\(SR\\.TypeMustImplementIAddChild, frameworkObject\\.DO\\.GetType\\(\\)\\.Name\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs","lineNumber":951,"sourceCode":"\n            // Set values for this object, taking them from the shared values table.\n\n            ProvideValueServiceProvider provideValueServiceProvider = null;\n            FrameworkTemplate.SetTemplateParentValues( Name, frameworkObject.DO, _frameworkTemplate, ref provideValueServiceProvider );\n\n            // Get the first child\n\n            FrameworkElementFactory childFactory = _firstChild;\n\n            // If we have children, get this object's IAddChild, because it's going to be a parent.\n\n            IAddChild iAddChild = null;\n            if( childFactory != null )\n            {\n                iAddChild = frameworkObject.DO as IAddChild;\n                if (iAddChild == null)\n                {\n                    throw new InvalidOperationException(SR.Format(SR.TypeMustImplementIAddChild,\n                                                         frameworkObject.DO.GetType().Name));\n                }\n            }\n\n            // Build the children.\n\n            while (childFactory != null)\n            {\n\n                if (childFactory._text != null)\n                {\n                    iAddChild.AddText(childFactory._text);\n\n                }\n                else\n                {\n                    // Use frameworkObject's IAddChild to add this node.\n                    FrameworkObject childFrameworkObject = childFactory.InstantiateUnoptimizedTree();","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs#L933-L969","documentation":"In InstantiateUnoptimizedTree, when the current node has a childFactory, the framework expects the instantiated parent object to implement IAddChild so the child can be attached. If frameworkObject.DO does not implement IAddChild, an InvalidOperationException naming the parent's type is thrown. This guards the child-attachment contract during template instantiation.","triggerScenarios":"A FrameworkElementFactory tree where node A has appended children (childFactory != null) and A's type, when instantiated, does not implement IAddChild; triggered when the template tree is instantiated unoptimized.","commonSituations":"Appending child factories to a parent type that only accepts children through a specialized API (not IAddChild); custom controls used as template roots/interior nodes; version changes where a control no longer implements IAddChild.","solutions":["Choose an interior parent type that implements IAddChild (e.g. ContentControl, Panel types, Decorator).","Implement IAddChild on the custom parent type.","Restructure the factory tree so children attach through the parent's native content property instead of AppendChild."],"exampleFix":"// before\nvar root = new FrameworkElementFactory(typeof(MyControl)); // MyControl has no IAddChild\nroot.AppendChild(new FrameworkElementFactory(typeof(Button)));\n// after\nclass MyControl : ContentControl { ... } // or use ContentControl directly","handlingStrategy":"type-guard","validationCode":"if (rootFactory.Type != null && !typeof(IAddChild).IsAssignableFrom(rootFactory.Type) && rootHasChildren)\n    throw new InvalidOperationException($\"{rootFactory.Type.Name} cannot host child factories\");","typeGuard":"bool SupportsChildren(Type t) => typeof(IAddChild).IsAssignableFrom(t);","tryCatchPattern":"try { template.LoadContent(); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"IAddChild\")) { /* replace root/parent type */ }","preventionTips":["Only AppendChild onto factories whose type implements IAddChild","Prefer standard controls (Grid, StackPanel, ContentControl) as interior nodes","Recheck compatibility after upgrading custom control libraries"],"tags":["wpf","template","iaddchild","type-mismatch"],"backgroundTag":"incompatible-source-type","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}