{"record":{"id":"d72ca5d113ea58a5","repo":"dotnet/wpf","slug":"sr-cannotbeselfparent","errorCode":null,"errorMessage":"SR.CannotBeSelfParent","messagePattern":"SR\\.CannotBeSelfParent","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs","lineNumber":306,"sourceCode":"            // (This is a noop if this object is not assigned to a Dispatcher.)\n            //\n            // We also need to ensure that the tree is homogenous with respect\n            // to the dispatchers that the elements belong to.\n            //\n            this.VerifyAccess();\n            newParent?.VerifyAccess();\n\n            // Logical Parent must first be dropped before you are attached to a newParent\n            // This mitigates illegal tree state caused by logical child stealing as illustrated in bug 970706\n            if (_parent != null && newParent != null && _parent != newParent)\n            {\n                throw new System.InvalidOperationException(SR.HasLogicalParent);\n            }\n\n            // Trivial check to avoid loops\n            if (newParent == this)\n            {\n                throw new System.InvalidOperationException(SR.CannotBeSelfParent);\n            }\n\n            // invalid during a VisualTreeChanged event\n            VisualDiagnostics.VerifyVisualTreeChange(this);\n\n            // Logical Parent implies no InheritanceContext\n            if (newParent != null)\n            {\n                ClearInheritanceContext();\n            }\n\n            IsParentAnFE = newParent is FrameworkElement;\n\n            DependencyObject oldParent = _parent;\n            OnNewParent(newParent);\n\n            // Update Has[Loaded/Unloaded]Handler Flags\n            BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag(this, oldParent, newParent);","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs#L288-L324","documentation":"ChangeLogicalParent also rejects self-parenting: if newParent == this, InvalidOperationException (CannotBeSelfParent) is thrown. Allowing an element to be its own logical parent would create a cycle, breaking tree invariants and infinite-walking the tree.","triggerScenarios":"Calling ChangeLogicalParent with the element itself, or code paths (AddLogicalChild on self, self-referential binding/content assignment) that end up attaching an element as its own child/parent.","commonSituations":"Recursive data structures rendered directly into themselves; programming errors in custom containers where 'this' is passed instead of the intended child; cyclic content assignment in templates.","solutions":["Verify the newParent argument is the intended ancestor, not the element itself.","Break data cycles before they reach the visual/logical tree (e.g. detect recursion in your model).","Add an assertion/guard in custom container code that child != this before attaching."],"exampleFix":"// before\nif (parent == null) parent = this; // wrong fallback\nthis.ChangeLogicalParent(parent);\n// after\nif (parent == null || parent == this)\n    throw new ArgumentException(\"Invalid logical parent\");\nthis.ChangeLogicalParent(parent);","handlingStrategy":"validation","validationCode":"if (ReferenceEquals(newParent, element)) throw new ArgumentException(\"Element cannot be its own logical parent\");","typeGuard":"static bool IsValidParent(DependencyObject self, DependencyObject candidate) => candidate != null && !ReferenceEquals(candidate, self);","tryCatchPattern":"try { element.ChangeLogicalParent(newParent); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"self\")) { Log(\"cycle detected\"); }","preventionTips":["Assert child != this in any custom Add/Change parent code.","Detect recursive object graphs in your model before rendering them.","Keep parent assignment centralized so accidental self-assignment is impossible."],"tags":["wpf","logical-tree","cycle","invalid-operation"],"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-21T21:30:21.729Z"}