{"record":{"id":"cfe66c9500f24287","repo":"dotnet/wpf","slug":"sr-cannotmodifylogicalchildrenduringtreewalk","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/FrameworkContentElement.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/FrameworkContentElement.cs#L174-L210","documentation":"AddLogicalChild refuses to modify the logical children collection while a property-invalidation tree walk is iterating it. WPF throws InvalidOperationException (CannotModifyLogicalChildrenDuringTreeWalk) because changing the collection during enumeration corrupts the walk. This is an explicit reentrancy guard.","triggerScenarios":"Adding a logical child from within a callback invoked during property invalidation tree traversal — e.g. a PropertyChangedCallback, OnVisualParentChanged-style notifications, or a layout/measure callback that calls AddLogicalChild.","commonSituations":"Deferring element creation into property-change handlers; workarounds in style/resource callbacks that reparent elements; bug fixes that mutate tree structure inside DataContext or resource-change notifications.","solutions":["Defer the AddLogicalChild call until after the tree walk: use Dispatcher.BeginInvoke(DispatcherPriority.Loaded, ...).","Move the logical-tree change out of invalidation callbacks into explicit lifecycle points (Loaded/Initialized).","Restructure so children are added before properties that trigger the walk are set."],"exampleFix":"// before\nvoid OnDpChanged(...) { parent.AddLogicalChild(newChild); }\n// after\nvoid OnDpChanged(...) {\n  Dispatcher.BeginInvoke(DispatcherPriority.Loaded,\n    new Action(() => parent.AddLogicalChild(newChild)));\n}","handlingStrategy":"try-catch","validationCode":"if (parent.IsLogicalChildrenIterationInProgress)\n    Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => parent.AddLogicalChild(child)));\nelse\n    parent.AddLogicalChild(child);","typeGuard":null,"tryCatchPattern":"try { parent.AddLogicalChild(child); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"tree walk\")) { Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => parent.AddLogicalChild(child))); }","preventionTips":["Never mutate the logical tree inside property-change/invalidation callbacks; defer via Dispatcher.","Restructure code so structural changes happen in Loaded/Initialized lifecycle points.","Add a unit test that triggers the invalidation path to catch reentrancy early."],"tags":["wpf","logical-tree","reentrancy","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"}