dotnet/wpf · error · InvalidOperationException
Unable to combine two HRGNs.
Error message
Unable to combine two HRGNs.
What it means
When WindowChromeWorker builds the custom window region, it combines a rounded-rectangle HRGN into an existing region with the Win32 CombineRgn API. If CombineRgn returns ERROR, the code throws InvalidOperationException after cleaning up the native region handle, since the window region cannot be computed.
Solutions
- Check for GDI handle leaks (GDI Objects count in Task Manager) and fix leaked HRGN/HDC/HBITMAP handles.
- Reduce concurrent custom-chromed windows or release unused window chrome regions.
- Catch the InvalidOperationException and fall back to the default (non-rounded) window region.
- Restart the process if GDI exhaustion is persistent; keep the SafeDeleteObject cleanup path (the library already does this).
Example fix
// before
WindowChromeWorker._UpdateRegion(...) // throws on GDI failure
// after
try { chromeWorker.UpdateWindowRegion(); }
catch (InvalidOperationException ex)
{
// fall back to default rectangular window region
Trace.WriteLine("Region combine failed: " + ex.Message);
} Defensive patterns
Strategy: try-catch
Validate before calling
int gdiCount = GetGuiResources(Process.GetCurrentProcess().Handle, 0); // GR_GDIOBJECTS
if (gdiCount > 9000)
throw new InvalidOperationException("GDI handle exhaustion imminent"); Try / catch
try { worker.UpdateWindowRegion(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("HRGN"))
{ /* fall back to default rectangular region */ } Prevention
- Fix GDI handle leaks (delete HRGN/HDC/HBITMAP via DeleteObject).
- Monitor the GDI Objects column in Task Manager in long-running apps.
- Limit the number of simultaneously custom-chromed windows.
- Wrap chrome-region updates in try/catch with a fallback to the default region.
When it happens
Trigger: CombineRgn(hrgnSource, hrgnSource, hrgn, RGN.OR) returning ERROR — typically when one of the HRGN handles is invalid or GDI resources/handles are exhausted.
Common situations: GDI handle leaks in the process exhausting resources; many concurrent custom-chromed windows; low-memory or remote-desktop sessions with constrained GDI; invalid region after prior native failures.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to initialize GestureRecognizer.
- Failed to set enabled gestures.
- Gesture recognition failed.
- message (formatted LS error message, e.g. SR.SetTabsFailure…
- PrintConfig.Provider.BindFail
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/4d0238c7f13b7be0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Shell/WindowChromeWorker.cs:892
(int)Math.Floor(region.Left),
(int)Math.Floor(region.Top),
(int)Math.Ceiling(region.Right) + 1,
(int)Math.Ceiling(region.Bottom) + 1,
(int)Math.Ceiling(radius),
(int)Math.Ceiling(radius));
}
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HRGNs")]
private static void _CreateAndCombineRoundRectRgn(IntPtr hrgnSource, Rect region, double radius)
{
IntPtr hrgn = IntPtr.Zero;
try
{
hrgn = _CreateRoundRectRgn(region, radius);
CombineRgnResult result = NativeMethods.CombineRgn(hrgnSource, hrgnSource, hrgn, RGN.OR);
if (result == CombineRgnResult.ERROR)
{
throw new InvalidOperationException("Unable to combine two HRGNs.");
}
}
catch
{
Utility.SafeDeleteObject(ref hrgn);
throw;
}
}
private static bool _IsUniform(CornerRadius cornerRadius)
{
if (!DoubleUtilities.AreClose(cornerRadius.BottomLeft, cornerRadius.BottomRight))
{
return false;
}
if (!DoubleUtilities.AreClose(cornerRadius.TopLeft, cornerRadius.TopRight))
{View on GitHub (pinned to 81131a70a4)