stablyai/orca · error · BrowserError

browser_error

browser_error

Error message

Could not attach debugger. DevTools may already be open for this tab.

What it means

Electron permits only one CDP debugger session per WebContents. acquireElectronDebugger() calls debugger.attach('1.3'); if DevTools is already open for that tab or another CDP consumer (screencast, WS proxy, agent-browser) already holds the debugger, the attach rejects and startBrowserScreencast converts it to this browser_error. The lease system (electron-debugger-lease.ts) allows multiple consumers to share one attach via a Symbol-owner Set, but an external attach (DevTools) bypasses that mechanism.

Source

Thrown at src/main/browser/browser-screencast-stream.ts:232

      clearTimeout(timeout)
    }
  }
}

export async function startBrowserScreencast(
  webContents: WebContents,
  options: BrowserScreencastOptions
): Promise<BrowserScreencastSession> {
  if (webContents.isDestroyed()) {
    throw new BrowserError('browser_tab_not_found', 'Browser tab is no longer available')
  }

  const dbg = webContents.debugger
  let debuggerLease: ElectronDebuggerLease | null = null
  try {
    debuggerLease = acquireElectronDebugger(webContents)
  } catch {
    throw new BrowserError(
      'browser_error',
      'Could not attach debugger. DevTools may already be open for this tab.'
    )
  }

  let closed = false
  let stopping = false
  let seq = 0
  let lastFrameSentAt = 0
  let deviceMetricsOverridden = false
  let snapshotGeneration = 0
  let navigationCaptureTimer: ReturnType<typeof setTimeout> | null = null
  let pendingFrame: PendingScreencastFrame | null = null
  let pendingFrameTimer: ReturnType<typeof setTimeout> | null = null
  let resolveDone!: () => void
  const done = new Promise<void>((resolve) => {
    resolveDone = resolve
  })

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Close DevTools for that browser tab, then retry.
  2. Stop any other screencast or CDP-WS-proxy session on the same WebContents.
  3. Retry after ensuring only one consumer holds the debugger lease.

Example fix

// before
const session = await startBrowserScreencast(wc, opts)

// after
try {
  const session = await startBrowserScreencast(wc, opts)
} catch (e) {
  if (e instanceof BrowserError && e.code === 'browser_error' && /DevTools/.test(e.message)) {
    // prompt user to close DevTools, then retry
  }
  throw e
}
Defensive patterns

Strategy: try-catch

Validate before calling

const dbg = webContents.debugger
if (dbg.isAttached()) {
  // debugger already held by another consumer; either reuse via lease or ask user to close DevTools
}
const session = await startBrowserScreencast(webContents, options)

Try / catch

try {
  const session = await startBrowserScreencast(wc, opts)
} catch (e) {
  if (e instanceof BrowserError && e.code === 'browser_error' && /DevTools/.test(e.message)) {
    // prompt user to close DevTools for this tab, then retry
  }
  throw e
}

Prevention

When it happens

Trigger: Calling startBrowserScreencast while DevTools is open on that tab; a prior screencast session crashed without releasing its debugger lease; the CDP WS proxy is connected to the same WebContents.

Common situations: Developer left DevTools open during testing; a crashed screencast whose lease was never released; two Orca features competing for the same tab's debugger.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/3e818937f405364a. Report an issue: GitHub.