dotnet/wpf · error · InvalidOperationException

InvalidOperationException

Error message

InvalidOperationException

What it means

CheckForCreateWindowFailure validates the result of CreateWindowEx inside HwndWrapper.WndProc. CreateWindowEx sends WM_CREATE (and WM_NCCREATE) synchronously, so a non-zero result with handled=true during creation means a handler claimed to handle a creation message but returned an invalid result — an internal invariant violation, surfaced as InvalidOperationException.

Solutions

  1. Do not set handled=true for WM_NCCREATE/WM_CREATE messages in custom WndProc hooks, or return the correct result when doing so
  2. Fix the hook so it returns 0/continues default processing for creation messages it does not fully handle
  3. Reproduce under a debugger — the code deliberately breaks there to identify the offending handler
  4. Check recently added WndProcHook callbacks registered on this HwndWrapper

Example fix

// before
case WM_CREATE:
    handled = true;
    return 1; // non-zero result with handled -> InvalidOperationException
// after
case WM_CREATE:
    return 0; // let default processing continue, handled stays false
Defensive patterns

Strategy: try-catch

Try / catch

try { wrapper.Create(); } catch (InvalidOperationException ex) { log("WM_CREATE handler returned invalid result", ex); throw; }

Prevention

When it happens

Trigger: A WM_NCCREATE/WM_CREATE handler in the WndProc pipeline sets handled=true while returning a non-zero (non-HWND-success) result during CreateWindowEx, most often from a custom WndProcHook or subclass that mishandles creation messages.

Common situations: Custom HwndWrapper subclasses or injected hooks that mark WM_CREATE handled and return wrong values; running under a debugger-detached environment where the Debug.Break path is skipped.

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/ef2592af2dd0a339. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/Shared/MS/Win32/HwndWrapper.cs:295

            // return our result
            return result;
        }

        private void CheckForCreateWindowFailure( IntPtr result, bool handled )
        {
            if( ! _isInCreateWindow )
                return;
            
            if( IntPtr.Zero != result )
            {
                System.Diagnostics.Debug.WriteLine("Non-zero WndProc result=" + result);
                if( handled )
                {
                    if( System.Diagnostics.Debugger.IsAttached )
                        System.Diagnostics.Debugger.Break();
                    else
                        throw new InvalidOperationException();
                }
            }
        }


        /// <summary>
        /// Destroys the window with the given handle and class atom and unregisters its window class
        /// </summary>
        /// <param name="args">A DestrowWindowParams instance</param>
        internal static object DestroyWindow(object args)
        {
            nint handle = ((DestroyWindowArgs)args).Handle;
            ushort classAtom = ((DestroyWindowArgs)args).ClassAtom;

            Invariant.Assert(handle != 0,
               "Attempting to destroy an invalid hwnd");

            UnsafeNativeMethods.DestroyWindow(new HandleRef(null, handle));

View on GitHub (pinned to 81131a70a4)