CherryHQ/cherry-studio · error · Error

MCP browser window not found after open

Error message

MCP browser window not found after open

What it means

In createBrowserWindow, windowManager.open() returns a windowId but the immediately following windowManager.getWindow(windowId) returns null/undefined. This means the McpBrowser window was destroyed or removed from the registry between open and lookup — an invariant violation of the WindowManager contract.

Source

Thrown at src/main/ai/mcp/servers/browser/controller.ts:368

  }

  private async createBrowserWindow(
    windowKey: string,
    privateMode: boolean,
    showWindow = false
  ): Promise<{ window: BrowserWindow; windowId: string }> {
    await this.ensureAppReady()

    const windowManager = application.get('WindowManager')
    // The per-mode session partition is the only dynamic option; everything else
    // lives in the WindowType.McpBrowser registry entry.
    const windowId = windowManager.open(WindowType.McpBrowser, {
      options: { webPreferences: { partition: this.getPartition(privateMode) } }
    })
    const win = windowManager.getWindow(windowId)
    if (!win) {
      windowManager.close(windowId)
      throw new Error('MCP browser window not found after open')
    }
    if (showWindow) win.show()

    win.on('closed', () => {
      const windowInfo = this.windows.get(windowKey)
      if (windowInfo) {
        const tabIds = Array.from(windowInfo.tabs.keys())
        for (const tabId of tabIds) {
          this.closeTabInternal(windowInfo, tabId)
        }
        this.windows.delete(windowKey)
      }
    })

    return { window: win, windowId }
  }

  private async getOrCreateWindow(privateMode: boolean, showWindow = false): Promise<WindowInfo> {

View on GitHub (pinned to 726446b54c)

Solutions

  1. Check the WindowType.McpBrowser entry in windowRegistry.ts for correct mode/lifecycle settings.
  2. Ensure no concurrent dispose()/shutdown is racing the call — gate browser-tool calls on app readiness (ensureAppReady is already called).
  3. Inspect logs for a synchronously-fired 'closed' event or GPU/process crash on the McpBrowser window.
  4. Retry once after a short delay; if it persists, report a WindowManager state corruption.
  5. Limit concurrent createBrowserWindow calls to avoid pool exhaustion.

Example fix

// before
const windowId = windowManager.open(WindowType.McpBrowser, { options: { webPreferences: { partition } } })
const win = windowManager.getWindow(windowId)
if (!win) {
  windowManager.close(windowId)
  throw new Error('MCP browser window not found after open')
}

// after — retry once and surface the underlying registry/WM failure
let win = windowManager.getWindow(windowId)
if (!win) {
  await new Promise((r) => setTimeout(r, 50))
  win = windowManager.getWindow(windowId)
}
if (!win) {
  throw new Error(`MCP browser window ${windowId} not found after open; McpBrowser registry or pool may be misconfigured`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Guard browser-window creation against an immediately-vanishing window
async function openBrowserWindow(windowManager, privateMode) {
  const windowId = windowManager.open(WindowType.McpBrowser, { options: { webPreferences: { partition: getPartition(privateMode) } } })
  let win = windowManager.getWindow(windowId)
  if (!win) {
    await new Promise((r) => setTimeout(r, 50))
    win = windowManager.getWindow(windowId)
  }
  if (!win) throw new Error(`MCP browser window ${windowId} not available; McpBrowser registry or pool issue`)
  return { win, windowId }
}

Try / catch

try {
  return await openBrowserWindow(windowManager, privateMode)
} catch (e) {
  logger.error('McpBrowser window creation failed', { error: e.message })
  throw e
}

Prevention

When it happens

Trigger: WindowType.McpBrowser registry entry is misconfigured; the open() triggered an immediate close (e.g. a 'closed' event fired synchronously during open); WindowManager pool exhausted and the window was reclaimed instantly; or a concurrent dispose() raced the creation.

Common situations: App shutting down while a browser tool call arrives; multiple concurrent browser-tool invocations stressing the window pool; a malformed McpBrowser registry entry; Electron failed to construct the BrowserWindow (GPU crash) and it was destroyed on creation.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/6e3d9456e8f3ef67. Report an issue: GitHub.