stablyai/orca · warning · BrowserError
browser_tab_not_found
browser_tab_not_found
Error message
Tab index ${index} is out of range. ${liveEntries.length} tab(s) open. What it means
tabSwitch(index) resolves the target tab by its zero-based position among live tabs. The live count is computed by filtering the registry for WebContents that still exist and are not destroyed, so stale entries do not inflate the count. If index is negative or >= liveEntries.length, the switch is rejected. The indices shown here match those returned by tabList(), which applies the same filter.
Source
Thrown at src/main/browser/cdp-bridge.ts:986
index,
url: guest.getURL(),
title: guest.getTitle(),
active: wcId === this.activeWebContentsId
})
index++
}
return { tabs }
}
async tabSwitch(index: number): Promise<BrowserTabSwitchResult> {
// Why: filter to live tabs so indices match tabList(), skipping destroyed-but-uncleaned entries.
const liveEntries = [...this.getRegisteredTabs()].filter(([_, wcId]) => {
const guest = webContents.fromId(wcId)
return guest && !guest.isDestroyed()
})
if (index < 0 || index >= liveEntries.length) {
throw new BrowserError(
'browser_tab_not_found',
`Tab index ${index} is out of range. ${liveEntries.length} tab(s) open.`
)
}
const [tabId, wcId] = liveEntries[index]
if (this.activeWebContentsId !== null) {
this.invalidateRefMap(this.activeWebContentsId)
}
this.activeWebContentsId = wcId
return { switched: index, browserPageId: tabId }
}
onTabClosed(webContentsId: number): void {
if (this.activeWebContentsId === webContentsId) {
this.activeWebContentsId = null
}View on GitHub (pinned to 1136503c6a)
Solutions
- Call tabList() immediately before tabSwitch() to get the current live-tab indices.
- Validate the index against the returned tab count before passing it.
- Do not cache indices across operations that may open or close tabs.
Example fix
// before
await bridge.tabSwitch(5)
// after
const { tabs } = bridge.tabList()
if (index < 0 || index >= tabs.length) {
throw new Error(`Index ${index} out of range (0..${tabs.length - 1})`)
}
await bridge.tabSwitch(index) Defensive patterns
Strategy: validation
Validate before calling
const { tabs } = bridge.tabList()
if (index < 0 || index >= tabs.length) {
throw new Error(`Tab index ${index} out of range (0..${tabs.length - 1})`)
}
await bridge.tabSwitch(index) Type guard
function isValidTabIndex(index: number, tabCount: number): boolean {
return Number.isInteger(index) && index >= 0 && index < tabCount
} Prevention
- Call tabList() immediately before tabSwitch() — indices reflect only live tabs and can change when tabs close.
- Never cache tab indices across operations that may open or close tabs.
- Validate the index against the current live-tab count before passing it.
When it happens
Trigger: Passing an out-of-range index to tabSwitch; the number of live tabs changed between tabList() and tabSwitch() because a tab was closed in the interim.
Common situations: Hardcoding an index that becomes invalid when a tab closes; calling tabSwitch with an index from a stale tabList; off-by-one when iterating tabs.
Related errors
- browser_tab_not_found
- browser_no_tab
- browser_debugger_detached
- ${response.error.message}
- ${response.error.message || fallbackMessage}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/656447a4ab1d3422.
Report an issue: GitHub.