different-ai/openwork · error · Error

Unknown browser tab: ${tabId}

Error message

Unknown browser tab: ${tabId}

What it means

selectBrowserTab looks up the requested id in the browserTabs map and throws when it is absent. The caller referenced a tab that does not exist in the built-in browser panel's current session.

Source

Thrown at apps/desktop/electron/browser-panel.mjs:621

  function attachActiveBrowserView() {
    const mainWindow = window();
    if (!mainWindow || !browserViewVisible) return;
    const view = getActiveBrowserView();
    if (!view) return;
    for (const tab of browserTabs.values()) {
      if (tab.view !== view) detachBrowserView(tab.view);
    }
    if (!mainWindow.contentView.children.includes(view)) {
      mainWindow.contentView.addChildView(view);
    }
    if (lastBrowserBounds && lastBrowserBounds.width > 0 && lastBrowserBounds.height > 0) {
      view.setBounds(scaleRendererBounds(lastBrowserBounds));
    }
  }

  function selectBrowserTab(tabId) {
    if (!browserTabs.has(tabId)) throw new Error(`Unknown browser tab: ${tabId}`);
    hideMenuOverlay();
    const previousView = getActiveBrowserView();
    activeBrowserTabId = tabId;
    if (previousView && previousView !== getActiveBrowserView()) {
      detachBrowserView(previousView);
    }
    attachActiveBrowserView();
    sendBrowserState();
    return getBrowserTab(tabId);
  }

  function closeBrowserTab(tabId = activeBrowserTabId) {
    const tab = getBrowserTab(tabId);
    if (!tab) return null;
    if (menuOverlayRequest?.tabId === tabId) hideMenuOverlay();
    const closingIndex = browserTabOrder.indexOf(tabId);
    const wasActive = activeBrowserTabId === tabId;
    detachBrowserView(tab.view);

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Refresh the tab list (listBrowserTabs/browser state) and use a current tabId
  2. Check the tab still exists before selecting it
  3. Update stale UI references when tabs close (listen for tab-closed state updates)
  4. Reopen the tab or start a new tab if the old one is genuinely gone

Example fix

// before
selectBrowserTab(oldTabId);
// after
const tabs = listBrowserTabs();
if (tabs.some(t => String(t.tabId) === String(oldTabId))) selectBrowserTab(oldTabId);
Defensive patterns

Strategy: type-guard

Validate before calling

function tabExists(tabId) {
  return listBrowserTabs().some(t => String(t.tabId) === String(tabId));
}
if (!tabExists(tabId)) return; // skip selection

Type guard

function isOpenTab(tabId, tabs) { return tabs.some(t => String(t.tabId) === String(tabId)); }

Try / catch

try {
  selectBrowserTab(tabId);
} catch (e) {
  if (e.message.startsWith('Unknown browser tab:')) {
    // refresh tab state, select the first open tab instead
    const tabs = listBrowserTabs();
    if (tabs.length) selectBrowserTab(tabs[0].tabId);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the select-tab IPC/API with a stale or fabricated tabId: the tab was already closed, IDs from a previous app session are reused, an off-by-one/typo'd ID, or the panel was reloaded resetting tab state.

Common situations: UI keeping a reference to a closed tab and letting the user click it; scripts replaying old tab IDs; a tab closed asynchronously while automation still targets it; string vs number id mismatch if the caller doesn't match the map's key type.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/9fd14a6e899dcbde. Report an issue: GitHub.