cefsharp/CefSharp · error · DevToolsClientException
Failed to execute dev tools method {0}.
Error message
Failed to execute dev tools method {0}. What it means
Thrown by the private ExecuteDevToolsMethod helper when IBrowserHost.ExecuteDevToolsMethod returns 0. A zero return means the native CEF call did not dispatch the DevTools protocol message - typically because the browser/host is not ready (no underlying WebContents), the method name is unknown, or the host is shutting down. The exception text formats in the method name that failed.
Source
Thrown at CefSharp.Core/DevTools/DevToolsClient.cs:188
});
}
else
{
queuedCommandResults.TryRemove(messageId, out methodResultContext);
throw new DevToolsClientException("Unable to invoke ExecuteDevToolsMethod on CEF UI Thread.");
}
return taskCompletionSource.Task;
}
private void ExecuteDevToolsMethod(IBrowserHost browserHost, int messageId, string method, IDictionary<string, object> parameters, DevToolsMethodResponseContext methodResultContext)
{
try
{
var returnedMessageId = browserHost.ExecuteDevToolsMethod(messageId, method, parameters);
if (returnedMessageId == 0)
{
throw new DevToolsClientException(string.Format("Failed to execute dev tools method {0}.", method));
}
else if (returnedMessageId != messageId)
{
//For some reason our message Id's don't match
throw new DevToolsClientException(string.Format("Generated MessageId {0} doesn't match returned Message Id {1}", returnedMessageId, messageId));
}
}
catch (Exception ex)
{
queuedCommandResults.TryRemove(messageId, out _);
methodResultContext.SetException(ex);
}
}
/// <inheritdoc/>
public void Dispose()
{
//Dispose can be called from different ThreadsView on GitHub (pinned to 16bc6e0711)
Solutions
- Wait for the browser's IsBrowserInitializedChanged event (IsBrowserInitialized == true) before issuing DevTools commands.
- Prefer the generated strongly-typed DevTools domain client (e.g. client.Network.EnableAsync()) over raw method strings - it uses names valid for the bundled CEF.
- Verify the method name is supported by the Chromium version embedded in your CefSharp package (check the DevTools protocol schema for that CEF major version).
- Await the Task and handle DevToolsClientException with a retry/recovery policy for transient 'not yet ready' states.
Example fix
// before - host not ready
await browser.GetDevToolsClient().ExecuteDevToolsMethodAsync<object>("Page.reload", null); // returns 0
// after - wait for init, use typed client
await ((Task)browser.SynchronizationContextAsync()); // ensure initialized
if (!browser.IsBrowserInitialized) await WaitForInit(browser);
await client.Page.ReloadAsync(); Defensive patterns
Strategy: validation
Validate before calling
// Wait for browser init before sending DevTools commands.
if (!browser.IsBrowserInitialized)
await Task.Run(() => { while (!browser.IsBrowserInitialized) Thread.Sleep(20); });
await client.Page.ReloadAsync(); Type guard
public static bool BrowserReadyForDevTools(IBrowser b) => b != null && !b.IsDisposed && b.IsBrowserInitialized;
Try / catch
try { await client.Page.ReloadAsync(); }
catch (DevToolsClientException ex) when (ex.Message.StartsWith("Failed to execute dev tools method"))
{ /* host not ready / unknown method - retry or fall back */ } Prevention
- Use generated typed domain clients (client.Page.*, client.Network.*) rather than raw method strings
- Wait for IsBrowserInitialized before any DevTools call
- Confirm method names exist in the Chromium version bundled with your CefSharp package
When it happens
Trigger: Calling a DevTools method before the browser's underlying host/WebView is initialized; passing an empty or unrecognised method string; calling after the host is being torn down. The thrown exception is captured and routed to the awaiting Task via methodResultContext.SetException, so the caller observes it as a faulted Task rather than a synchronous throw.
Common situations: Sending DevTools commands in OnFrameLoadStart before IsBrowserInitialized; typos in raw method names when using the untyped ExecuteDevToolsMethodAsync(string, dict) overload; version skew where a method exists in newer Chromium but not the CEF build shipped with the CefSharp version in use.
Related errors
- IBrowser
- Unable to add MessageId {0} to queuedCommandResults Concurre
- Unable to invoke ExecuteDevToolsMethod on CEF UI Thread.
- Generated MessageId {0} doesn't match returned Message Id {1
- Not currently supported.
AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13).
Data as JSON: /api/errors/80f0b2e6cf7e951b.
Report an issue: GitHub.