chenglou/pretext · error · Error

${tree.message ?? tree.error}

Error message

${tree.message ?? tree.error}

What it means

Thrown during Firefox session initialization when the WebDriver BiDi 'browsingContext.getTree' command returns an error. This call happens after session.new succeeded (error 16 did not fire), so the BiDi session is valid but listing browsing contexts failed. The thrown message uses tree.message if present, else tree.error.

Source

Thrown at scripts/browser-automation.ts:386

  ], {
    cwd: process.cwd(),
    stdio: 'ignore',
  })

  let bidi: FirefoxBidiClient | null = null

  try {
    await waitForPort(bidiPort)
    bidi = await connectFirefoxBidi(bidiPort)

    const session = await bidi.send('session.new', { capabilities: { alwaysMatch: {} } })
    if (session.error !== undefined) {
      throw new Error(session.message ?? session.error)
    }

    const tree = await bidi.send('browsingContext.getTree', {})
    if (tree.error !== undefined) {
      throw new Error(tree.message ?? tree.error)
    }

    const contexts = (tree.result as { contexts: Array<{ context: string }> }).contexts
    const context = contexts[0]?.context
    if (context === undefined) {
      throw new Error('Firefox BiDi returned no browsing context')
    }

    return {
      bidi,
      context,
      firefoxProcess,
      profileDir,
    }
  } catch (error) {
    bidi?.close()
    try {
      firefoxProcess.kill('SIGTERM')

View on GitHub (pinned to ac49b09b7d)

Solutions

  1. Re-run — transient BiDi errors during context enumeration often clear on retry.
  2. Upgrade Firefox to a version with stable browsingContext.getTree support.
  3. If reproducible, add a short retry loop around getTree in initializeFirefoxSession (the current code calls it once).
  4. Launch Firefox manually with the same flags to see if getTree fails interactively.
Defensive patterns

Strategy: retry

Type guard

function isBidiTreeError(tree: { error?: unknown, message?: unknown }): boolean {
  return tree.error !== undefined
}

Try / catch

// Retry browsingContext.getTree a few times for transient enumeration errors.
let tree
for (let i = 0; i < 3; i++) {
  tree = await bidi.send('browsingContext.getTree', {})
  if (tree.error === undefined) break
  await sleep(250)
}
if (tree.error !== undefined) throw new Error(tree.message ?? tree.error)

Prevention

When it happens

Trigger: session.new succeeded but browsingContext.getTree returned an error — transient BiDi state, a Firefox internal error enumerating contexts, or the about:blank context not yet ready when the call landed. Rare relative to error 16.

Common situations: Timing race where the context tree is queried before Firefox finishes setting up the initial about:blank tab; a Firefox BiDi implementation bug on the installed version; intermittent BiDi protocol error under load.

Related errors


AI-assisted analysis of chenglou/pretext@ac49b09b7d (2026-08-12). Data as JSON: /api/errors/9576c5faff03b57f. Report an issue: GitHub.