dotnet/wpf · error · ArgumentException
SR.CircularOwnerChild
Error message
SR.CircularOwnerChild
What it means
Window.Owner setter throws ArgumentException when the new owner is one of the windows this window currently owns (a child in OwnedWindows). Making a window's own child its owner would create a circular owner/owned relationship, which WPF forbids. The message includes both window instances.
Solutions
- Choose a third window (or null) as the mutual owner instead of reversing the relationship.
- Clear the existing relationship first (set the child's Owner to null) before re-parenting.
- Guard the assignment with a check that value is not in this.OwnedWindows.
Example fix
// before childA.Owner = mainWindow; mainWindow.Owner = childA; // circular // after childA.Owner = mainWindow; // keep one-directional ownership
Defensive patterns
Strategy: validation
Validate before calling
bool isNotOwnedChild(Window self, Window candidate) => candidate == null || !self.OwnedWindows.OfType<Window>().Contains(candidate);
Try / catch
try { w.Owner = candidate; }
catch (ArgumentException) { candidate.Owner = null; w.Owner = candidate; } Prevention
- Model ownership as a strict tree, never cycles.
- Before re-parenting, explicitly clear existing Owner.
- Add debug asserts checking OwnedWindows before assignment.
When it happens
Trigger: Setting A.Owner = B when B is already owned by A (A owns B, then B tries to own A), detected by scanning OwnedWindows for the value.
Common situations: Swapping owner/owned relationships dynamically; accidentally assigning the same window reference incorrectly in factory code that wires up many windows.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.CannotSetOwnerToItself
- SR.CantSetOwnerAfterDialogIsShown
- SR.CantSetOwnerToClosedWindow
- SR.CantSetOwnerWhosHwndIsNotCreated
- SR.ChangeNotAllowedAfterShow
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d45682deccf7e02a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs:1262
}
if ( _ownerWindow == value )
{
return;
}
if (!_disposed)
{
// Check to see if value is already a child of this window.
// If yes, throw Exception
if (value != null)
{
WindowCollection ownedWindows = OwnedWindows;
for (int i = 0; i < ownedWindows.Count; i++)
{
if (ownedWindows[i] == value)
{
throw new ArgumentException(SR.Format(SR.CircularOwnerChild, value, this));
}
}
}
// Update OwnerWindows of the previous owner
// using OwnedWindowsInternl b/c we want to modifying the
// underlying collection
_ownerWindow?.OwnedWindowsInternal.Remove(this);
}
// Update parent handle. If value is null, then make parent
// handle IntPtr.Zero
_ownerWindow = value;
// We should not do anything if the window is already closed and maybe throw exception.
// In Dev10, it is unknown whether we can begin to throw exceptions, because it is a BC.
// In Dev10, we still update _ownerWindow after window is closed just so that the Owner getter
// returns the right value.View on GitHub (pinned to 81131a70a4)