cefsharp/CefSharp · error · InvalidOperationException

IBrowser instance is no longer valid. Control.Handle was lik

Error message

IBrowser instance is no longer valid. Control.Handle was likely destroyed.

What it means

Thrown by ChromiumWebBrowser.Load(string) when the IBrowserCore exists but IsValid is false, meaning the underlying CEF browser object has been torn down while the .NET wrapper still references it. The control handle was destroyed (form closing, tab disposed, reparenting) so navigation is impossible. Load guards disposal first (returns silently) but treats an invalid-but-not-disposed core as an error.

Source

Thrown at CefSharp.WinForms/ChromiumWebBrowser.cs:477

            var browserCore = BrowserCore;

            //There's a small window here between CreateBrowser
            //and OnAfterBrowserCreated where the Address prop
            //will be updated, no MainFrame.LoadUrl call will be made.
            if (browserCore == null)
            {
                Address = url;
            }
            else
            {
                if(browserCore.IsDisposed)
                {
                    return;
                }

                if(!browserCore.IsValid)
                {
                    throw new InvalidOperationException("IBrowser instance is no longer valid. Control.Handle was likely destroyed.");
                }

                using (var frame = browserCore.MainFrame)
                {
                    //Only attempt to call load if frame is valid
                    //I've seen so far one case where the MainFrame is invalid.
                    //As yet unable to reproduce
                    if (frame.IsValid)
                    {
                        frame.LoadUrl(url);
                    }
                }
            }
        }

        /// <summary>
        /// Capture page screenshot.
        /// </summary>

View on GitHub (pinned to 16bc6e0711)

Solutions

  1. Guard Load calls with `if (!browser.IsDisposed && browser.BrowserCore?.IsValid == true)` before navigating.
  2. Cancel background navigation tasks (CancellationToken) when the form/tab closes.
  3. Prefer the async `LoadUrlAsync` extension which handles lifecycle more gracefully, and await it with a cancellation token.
  4. Avoid calling Load from FormClosing/Dispose paths; queue the navigation or skip it if the handle is gone.

Example fix

// before
browser.Load(nextUrl); // throws if handle destroyed mid-session

// after
if (!browser.IsDisposed && browser.BrowserCore is { } core && core.IsValid)
{
    browser.Load(nextUrl);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!browser.IsDisposed && browser.BrowserCore is { } core && core.IsValid)
{
    browser.Load(url);
}

Try / catch

try { browser.Load(url); }
catch (InvalidOperationException ex) when (ex.Message.Contains("no longer valid"))
{
    // handle/control destroyed mid-navigation; abort gracefully
}

Prevention

When it happens

Trigger: Calling Load(url) while or after the control's handle is being destroyed: during Form.FormClosing, after removing the control from its parent, during tab teardown, or racing with asynchronous disposal.

Common situations: Navigating from a closing event handler; a background task calling Load after the user closed the tab/window; rapid open/close of browser instances; reparenting that recreates the handle.

Related errors


AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13). Data as JSON: /api/errors/726f626e7e92f7d3. Report an issue: GitHub.