{"record":{"id":"0688149559b3fc90","repo":"CherryHQ/cherry-studio","slug":"window-not-found-for-privatemode-private","errorCode":null,"errorMessage":"Window not found for ${privateMode ? 'private' : 'normal'} mode","messagePattern":"Window not found for (.+?) mode","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/servers/browser/controller.ts","lineNumber":928,"sourceCode":"\n  /**\n   * Closes a specific tab\n   * @param privateMode - If true, closes tab from private window (default: false)\n   * @param tabId - Tab identifier to close\n   */\n  public async closeTab(privateMode: boolean, tabId: string) {\n    await this.reset(privateMode, tabId)\n  }\n\n  /**\n   * Switches the active tab\n   * @param privateMode - If true, switches tab in private window (default: false)\n   * @param tabId - Tab identifier to switch to\n   */\n  public async switchTab(privateMode: boolean, tabId: string) {\n    const windowKey = this.getWindowKey(privateMode)\n    const windowInfo = this.windows.get(windowKey)\n    if (!windowInfo) throw new Error(`Window not found for ${privateMode ? 'private' : 'normal'} mode`)\n\n    const tab = windowInfo.tabs.get(tabId)\n    if (!tab) throw new Error(`Tab ${tabId} not found`)\n\n    // Remove previous active tab view (but NOT the tabBarView)\n    if (windowInfo.activeTabId && windowInfo.activeTabId !== tabId) {\n      const prevTab = windowInfo.tabs.get(windowInfo.activeTabId)\n      if (prevTab && !windowInfo.window.isDestroyed()) {\n        windowInfo.window.removeBrowserView(prevTab.view)\n      }\n    }\n\n    windowInfo.activeTabId = tabId\n\n    // Add the new active tab view\n    if (!windowInfo.window.isDestroyed()) {\n      windowInfo.window.addBrowserView(tab.view)\n      this.updateViewBounds(windowInfo)","sourceCodeStart":910,"sourceCodeEnd":946,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/browser/controller.ts#L910-L946","documentation":"switchTab computes a windowKey from privateMode and looks up this.windows.get(windowKey); if no window was ever created for that mode, it throws. switchTab assumes the window already exists — it does not auto-create.","triggerScenarios":"Calling switchTab(privateMode, tabId) before any window/tab exists for that mode — e.g. the agent calls switch_tab directly without first issuing a navigate/create_tab that would bootstrap the window via getOrCreateWindow.","commonSituations":"Agent invokes tools out of order (switch before open); the window for that mode was closed (the 'closed' handler deletes the entry) and the agent still holds a stale tabId; private vs. normal mode mismatch between calls.","solutions":["Ensure a window exists for the mode first — call navigate_to or create_tab (which go through getOrCreateWindow) before switchTab.","If exposing switchTab to agents, have it auto-create the window via getOrCreateWindow when absent, or return a clear 'no window open' result instead of throwing.","Verify the privateMode flag matches the window the tabId came from."],"exampleFix":"// before\nconst windowInfo = this.windows.get(windowKey)\nif (!windowInfo) throw new Error(`Window not found for ${privateMode ? 'private' : 'normal'} mode`)\n\n// after — bootstrap lazily or return a structured 'no window' result\nlet windowInfo = this.windows.get(windowKey)\nif (!windowInfo) {\n  await this.getOrCreateWindow(privateMode, false)\n  windowInfo = this.windows.get(windowKey)\n}\nif (!windowInfo) throw new Error(`Unable to establish ${privateMode ? 'private' : 'normal'} browser window`)","handlingStrategy":"validation","validationCode":"// Ensure a window exists for the mode before switching tabs\nasync function ensureWindowForMode(controller, privateMode) {\n  const windowKey = controller.getWindowKey(privateMode)\n  if (!controller.windows.get(windowKey)) {\n    await controller.getOrCreateWindow(privateMode, false)\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ensureWindowForMode(controller, privateMode)\n  return controller.switchTab(privateMode, tabId)\n} catch (e) {\n  return { content: [{ type: 'text', text: `No ${privateMode ? 'private' : 'normal'} browser window open` }], isError: true }\n}","preventionTips":["Always open a window (navigate/create) before switchTab.","Match the privateMode flag to the window the tabId belongs to.","Expose switchTab to agents only after a window is known to exist."],"tags":["electron","browser-tool","tabs","window-manager"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}