chenglou/pretext · error · Error
${session.message ?? session.error}
Error message
${session.message ?? session.error} What it means
Thrown during Firefox session initialization when the WebDriver BiDi 'session.new' command returns an error object. The BiDi client surfaces protocol-level errors as { error, message }; this throw picks message when present, else the error code. It means Firefox accepted the TCP connection (waitForPort passed) but its BiDi endpoint rejected session creation — typically a capability or version problem.
Source
Thrown at scripts/browser-automation.ts:381
'--profile',
profileDir,
'--remote-debugging-port',
String(bidiPort),
'about:blank',
], {
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,View on GitHub (pinned to ac49b09b7d)
Solutions
- Upgrade Firefox to a recent release with full WebDriver BiDi support.
- Launch Firefox manually with the same flags (--headless --new-instance --remote-debugging-port <port>) and check about:debugging / the console for capability errors.
- Clear the profile dir and let the script create a fresh one.
- Read the exact message field — it usually names the unsupported capability or version mismatch.
Defensive patterns
Strategy: fallback
Validate before calling
// Verify Firefox supports WebDriver BiDi before launching.
// (No runtime API; check the installed version against Mozilla's BiDi minimum.)
import { execFileSync } from 'node:child_process'
const ver = execFileSync('/Applications/Firefox.app/Contents/MacOS/firefox', ['--version'], { encoding: 'utf8' })
if (Number.parseInt(ver.match(/(\d+)\./)?.[1] ?? '0', 10) < 113) {
throw new Error('Firefox >= 113 required for WebDriver BiDi')
} Type guard
function isBidiError(reply: { error?: unknown, message?: unknown }): boolean {
return reply.error !== undefined
} Try / catch
// initializeFirefoxSession already cleans up Firefox on this error; the caller should retry once.
try {
session = await initializeFirefoxSession()
} catch (error) {
// one retry for transient capability negotiation failures
session = await initializeFirefoxSession()
} Prevention
- Keep Firefox updated to a recent release with stable WebDriver BiDi.
- Let the script create a fresh profile each run; do not reuse a locked profile.
- Read the BiDi message field to pinpoint the capability or version mismatch.
- Launch Firefox manually with the same flags to reproduce capability errors.
When it happens
Trigger: Firefox BiDi session.new returns { error: '...', message: '...' } — capability alwaysMatch:{} unsupported by the installed Firefox version; Firefox too old to support BiDi; the remote-debugging-port is a legacy Marionette endpoint rather than BiDi; profile incompatibility.
Common situations: Firefox version predates WebDriver BiDi support (need a recent version); a Firefox update changed BiDi capability negotiation; a corrupted profile passed via --profile; conflicting Marionette/RemoteProtocol flags.
Related errors
- ${tree.message ?? tree.error}
- Firefox BiDi returned no browsing context
- Timed out waiting for local port ${port}
- ${navigate.message ?? navigate.error}
- Firefox is not currently supported for keep-all oracle check
AI-assisted analysis of chenglou/pretext@ac49b09b7d (2026-08-12).
Data as JSON: /api/errors/c1483e5b3896e7e7.
Report an issue: GitHub.