Skip to content

WebUI toolbar crashes with kWebUIToolbarProcessOverheadExperiment enabled #4225

Open

Description

@dreamanlan

Summary

CEF's chrome-style browser hosting (e.g. CefBrowserView and Alloy-inside-Chrome configurations) forces the underlying Browser type to TYPE_POPUP. The new WebUI toolbar infrastructure, guarded by features::kWebUIToolbarProcessOverheadExperiment and features::IsWebUIToolbarEnabled(), assumes that InitialWebUIManager is always available via BrowserWindowFeatures. That manager is only registered for TYPE_NORMAL browsers in BrowserWindowFeatures::RegisterBraveShieldsFeature(), so CEF hosts hit either a null-deref crash or a partially-initialized toolbar that never paints on first show.

Version

CEF Version 150.0.7871.187

Affected files

  • chrome/browser/ui/views/toolbar/toolbar_view.cc
  • chrome/browser/ui/views/toolbar/webui_toolbar_web_view.cc

Root cause

  1. In ToolbarView::Init() the WebUI toolbar views are created whenever the feature flags are enabled, without checking browser_->type().
  2. In WebUIToolbarWebView::OnPageInitialized() the code calls InitialWebUIManager::From(browser_)->OnWebUIToolbarLoaded() without a null check.

Because CEF sets Browser::TYPE_POPUP for CefBrowserView-backed windows, BrowserWindowFeatures never creates InitialWebUIManager, so From(browser_) returns nullptr.

Proposed fix

The fix has two parts:

1. Guard WebUI toolbar creation by browser type in toolbar_view.cc

Only instantiate WebUIToolbarWebView when the browser is TYPE_NORMAL, matching the upstream registration guard in BrowserWindowFeatures:

--- chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -433,11 +433,24 @@ void ToolbarView::Init() {
         base::BindRepeating(callback, browser_, IDC_FORWARD), browser_));
   }
 
-  if (base::FeatureList::IsEnabled(
+  // CEF: WebUIToolbarWebView depends on InitialWebUIManager, which is only
+  // registered on BrowserWindowFeatures for TYPE_NORMAL browsers (see
+  // browser_window_features.cc). CEF hosts using CefBrowserView force the
+  // Browser type to TYPE_POPUP (see chrome_browser_host_impl.cc), so
+  // InitialWebUIManager is never created for them and any WebUIToolbarWebView
+  // instance ends up in a partially-initialized state (crashes without a
+  // defensive null check, and even with one the toolbar fails to paint on
+  // first show). Align the creation guard here with the upstream
+  // BrowserWindowFeatures registration guard so the new WebUI toolbar is
+  // only instantiated when the surrounding infrastructure is guaranteed to
+  // exist.
+  const bool is_normal_browser = browser_->type() == Browser::TYPE_NORMAL;
+  if (is_normal_browser &&
+      base::FeatureList::IsEnabled(
           features::kWebUIToolbarProcessOverheadExperiment)) {
     detached_toolbar_webview_ = std::make_unique<WebUIToolbarWebView>(
         browser_, browser_->command_controller(), /*location_bar=*/nullptr);
-  } else if (features::IsWebUIToolbarEnabled()) {
+  } else if (is_normal_browser && features::IsWebUIToolbarEnabled()) {
     toolbar_webview_ = AddChildView(std::make_unique<WebUIToolbarWebView>(
         browser_, browser_->command_controller(),
         std::move(webui_location_bar)));
2. Add a defensive null check in webui_toolbar_web_view.cc

This mirrors the existing defensive pattern already used elsewhere in the same file (e.g. the TakeToolbarContents() call site):

--- chrome/browser/ui/views/toolbar/webui_toolbar_web_view.cc
+++ chrome/browser/ui/views/toolbar/webui_toolbar_web_view.cc
@@ -512,7 +512,15 @@ void WebUIToolbarWebView::OnPageInitialized() {
     avatar_control_.Initialize();
   }
 
-  InitialWebUIManager::From(browser_)->OnWebUIToolbarLoaded();
+  // CEF: InitialWebUIManager is a BrowserWindowFeatures member that is not
+  // always registered in CEF's chrome-style hosting (e.g. Alloy-inside-Chrome
+  // configurations), so From(browser_) can return nullptr here. Match the
+  // defensive pattern already used elsewhere in this file (see the
+  // TakeToolbarContents() call site) to avoid a null-deref crash right after
+  // the WebUI toolbar page finishes initialization.
+  if (auto* manager = InitialWebUIManager::From(browser_)) {
+    manager->OnWebUIToolbarLoaded();
+  }
 }
Impact
Without these changes, CEF builds that enable the WebUI toolbar experiments will crash or show a blank toolbar in chrome-style hosted windows.

Environment
CEF branch: current master / M-latest
OS: observed on macOS, likely affects all platforms using CEF chrome-style hosting
Relevant feature flags: kWebUIToolbarProcessOverheadExperiment, IsWebUIToolbarEnabled()
Notes
The first patch is the preferred fix because it avoids creating the WebUI toolbar in a context where its dependencies do not exist. The second patch is a defensive fallback that prevents crashes if the toolbar is instantiated through any other path.

Activity

  1. changed the title [-]WebUI toolbar crashes or fails to paint in CEF chrome-style hosting because InitialWebUIManager is not registered for non-normal browsers[/-] [+]WebUI toolbar crashes with kWebUIToolbarProcessOverheadExperiment enabled[/+] on Jul 27, 2026
  2. magreenblatt commented on Jul 27, 2026

    @magreenblatt
    Collaborator

    Note that this doesn't currently impact Official builds because field trials are disabled. You can run dev builds with --disable-field-trial-config to avoid this crash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug reportchrome-styleRelated to Chome runtime + Chrome style

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions