{"record":{"id":"628b35c64734c84e","repo":"dotnet/wpf","slug":"sr-cannotmodifylogicalchildrenduringtreewalk-628b35","errorCode":null,"errorMessage":"SR.CannotModifyLogicalChildrenDuringTreeWalk","messagePattern":"SR\\.CannotModifyLogicalChildrenDuringTreeWalk","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkElement.cs","lineNumber":192,"sourceCode":"        {\n            return _parent;\n        }\n\n        // mark whether Add should be called *before* or *after* the element adds it to its structure\n        /// <summary>\n        ///     Called by an element when that element adds the given object to\n        ///     its logical tree.  FrameworkElement updates the affected\n        ///     logical tree parent pointers to keep in sync with this insertion\n        /// </summary>\n        protected internal void AddLogicalChild(object child)\n        {\n            if (child != null)\n            {\n                // It is invalid to modify the children collection that we\n                // might be iterating during a property invalidation tree walk.\n                if (IsLogicalChildrenIterationInProgress)\n                {\n                    throw new InvalidOperationException(SR.CannotModifyLogicalChildrenDuringTreeWalk);\n                }\n\n                // Now that the child is going to be added, the FE/FCE construction is considered finished,\n                // so we do not expect a change of InheritanceBehavior property,\n                // so we can pick up properties from styles and resources.\n                TryFireInitialized();\n\n                bool exceptionThrown = true;\n                try\n                {\n                    HasLogicalChildren = true;\n\n                    // Child is present; reparent him to this element\n                    FrameworkObject fo = new FrameworkObject(child as DependencyObject);\n                    fo.ChangeLogicalParent(this);\n\n                    exceptionThrown = false;\n                }","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkElement.cs#L174-L210","documentation":"AddLogicalChild refuses to modify the logical children collection while a property-invalidation tree walk is iterating that collection. Doing so would invalidate the enumerator mid-walk, so WPF throws InvalidOperationException (CannotModifyLogicalChildrenDuringTreeWalk).","triggerScenarios":"Calling AddLogicalChild from within a callback that runs during a property invalidation tree walk — e.g. inside OnPropertyChanged, OnApplyTemplate template expansion triggered by the walk, or a property-changed handler that attaches children.","commonSituations":"Lazy template/applying default children inside property-changed callbacks; adding child elements in response to an inherited property change ( DataContext, inherited attached properties); layout code triggered synchronously during the walk.","solutions":["Defer the AddLogicalChild call with Dispatcher.BeginInvoke/BeginInvoke(DispatcherPriority.Background) so it runs after the tree walk completes.","Move child-adding logic out of property-changed callbacks into OnApplyTemplate, Loaded, or initialization.","Restructure so the collection is not changed reactively during invalidation (e.g. set a flag and add children on the next layout pass)."],"exampleFix":"// before\nprotected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)\n{\n    if (e.Property == ItemsSourceProperty)\n        AddLogicalChild(BuildChild()); // throws during tree walk\n}\n\n// after\nprotected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)\n{\n    if (e.Property == ItemsSourceProperty)\n        Dispatcher.BeginInvoke(() => AddLogicalChild(BuildChild()));\n}","handlingStrategy":"try-catch","validationCode":"if (parent.IsLogicalChildrenIterationInProgress)\n    Dispatcher.BeginInvoke(() => parent.AddLogicalChild(child));\nelse\n    parent.AddLogicalChild(child);","typeGuard":null,"tryCatchPattern":"try\n{\n    parent.AddLogicalChild(child);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"logical children\"))\n{\n    Dispatcher.BeginInvoke(() => parent.AddLogicalChild(child)); // retry after the walk\n}","preventionTips":["Never add logical children from OnPropertyChanged or other property-invalidation callbacks.","Defer tree mutations with Dispatcher.BeginInvoke when reacting to property changes.","Perform child construction in OnApplyTemplate/Loaded instead of reactive handlers."],"tags":["wpf","logical-tree","invalid-operation","tree-walk"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}