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

  1. Check for GDI handle leaks (GDI Objects count in Task Manager) and fix leaked HRGN/HDC/HBITMAP handles.
  2. Reduce concurrent custom-chromed windows or release unused window chrome regions.
  3. Catch the InvalidOperationException and fall back to the default (non-rounded) window region.
  4. 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

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


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)