dotnet/wpf · error · InvalidOperationException
SR.CannotBeSelfParent
Error message
SR.CannotBeSelfParent
What it means
ChangeLogicalParent includes a trivial loop check: an element cannot be its own parent. If newParent == this, it throws InvalidOperationException(SR.CannotBeSelfParent). This prevents infinite parent chains and illegal tree structure.
Solutions
- Verify the arguments before parenting: assert(child != parent)
- Skip the call when newParent == this (it is a no-op semantically)
- Trace the re-parenting code path for cycles where an ancestor is re-added as a descendant
Example fix
// before child.ChangeLogicalParent(child); // after if (child != newParent) child.ChangeLogicalParent(newParent);
Defensive patterns
Strategy: validation
Validate before calling
if (ReferenceEquals(child, newParent)) throw new ArgumentException("An element cannot be its own logical parent."); Type guard
bool IsNotSelfParent(System.Windows.FrameworkElement child, object newParent) => !ReferenceEquals(child, newParent);
Try / catch
try { child.ChangeLogicalParent(newParent); } catch (InvalidOperationException ex) when (ex.Message.Contains("own parent")) { /* skip; self-parenting is a no-op */ } Prevention
- Assert child != parent before any parenting call
- Audit generic reparenting utilities for self-reference cycles
- Guard against recursive tree-building code that could re-add ancestors as children
When it happens
Trigger: Calling ChangeLogicalParent(element) on itself — e.g. accidentally passing 'this' instead of the intended child/parent in custom logical-tree code, or a cycle where a container ends up as its own child.
Common situations: Custom panel/content-control code wiring parents; recursion bugs where a node gets added to itself; generic re-parenting utilities mishandling self-references.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.CannotBeSelfParent
- SR.HasLogicalParent
- SR.HasLogicalParent
- ' ' must be the root element of a tree, but has a logical…
- exceptionMessage.ToString()
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5cd1a21bfb617f03.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/generators/FrameworkElementTemplate.cs:370
// (This is a noop if this object is not assigned to a Dispatcher.)
//
// We also need to ensure that the tree is homogenous with respect
// to the dispatchers that the elements belong to.
//
this.VerifyAccess();
newParent?.VerifyAccess();
// Logical Parent must first be dropped before you are attached to a newParent
// This mitigates illegal tree state caused by logical child stealing as illustrated in bug 970706
if (_parent != null && newParent != null && _parent != newParent)
{
throw new System.InvalidOperationException(SR.HasLogicalParent);
}
// Trivial check to avoid loops
if (newParent == this)
{
throw new System.InvalidOperationException(SR.CannotBeSelfParent);
}
// invalid during a VisualTreeChanged event
VisualDiagnostics.VerifyVisualTreeChange(this);
// Logical Parent implies no InheritanceContext
if (newParent != null)
{
ClearInheritanceContext();
}
IsParentAnFE = newParent is FrameworkElement;
DependencyObject oldParent = _parent;
OnNewParent(newParent);
// Update Has[Loaded/Unloaded]Handler Flags
BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag(this, oldParent, newParent);View on GitHub (pinned to 81131a70a4)