SeleniumHQ/selenium · error · TypeError
browsingContexts should be string or string array
Error message
browsingContexts should be string or string array
What it means
Thrown by BiDi session.subscribe() when the browsingContexts argument is neither a string nor an array of strings. After normalizing the argument through toArray(), the client validates that each context identifier is a string, because the session.subscribe command requires context IDs as strings. A non-string element would serialize to an invalid command payload, so it is rejected client-side first.
Source
Thrown at javascript/selenium-webdriver/bidi/index.js:259
}
return Array.isArray(arg) ? [...arg] : [arg]
}
const eventsArray = toArray(events)
const contextsArray = toArray(browsingContexts)
const params = {
method: 'session.subscribe',
params: {},
}
if (eventsArray.length && eventsArray.some((event) => typeof event !== 'string')) {
throw new TypeError('events should be string or string array')
}
if (contextsArray.length && contextsArray.some((context) => typeof context !== 'string')) {
throw new TypeError('browsingContexts should be string or string array')
}
if (eventsArray.length) {
params.params.events = eventsArray
}
if (contextsArray.length) {
params.params.contexts = contextsArray
}
this.events.push(...eventsArray)
await this.send(params)
}
/**
* Unsubscribe to events
* @param eventsView on GitHub (pinned to aa36b38e69)
Solutions
- Pass context identifiers as a string or an array of strings (e.g. subscribe('log.entryAdded', 'ctx12345') or subscribe('log.entryAdded', ['ctx12345','ctx67890'])).
- If you hold context objects, extract the id string first (e.g. info.context) before calling subscribe.
- Omit the browsingContexts argument entirely to subscribe globally, which avoids the check because undefined becomes an empty array.
Example fix
// before
const info = await browsingContext.create(contextDescriptor)
await bidi.subscribe('log.entryAdded', info) // info is an object
// after
await bidi.subscribe('log.entryAdded', info.context) // pass the id string Defensive patterns
Strategy: validation
Validate before calling
function assertStringContexts(contexts) {
const arr = Array.isArray(contexts) ? contexts : contexts === undefined ? [] : [contexts]
if (arr.length && arr.some((c) => typeof c !== 'string')) {
throw new TypeError('browsingContexts must be string or string[]')
}
return arr
} Type guard
function isContextIdList(v) {
if (v === undefined) return true
if (typeof v === 'string') return true
return Array.isArray(v) && v.every((c) => typeof c === 'string')
} Try / catch
try {
await bidi.subscribe(events, contexts)
} catch (e) {
if (e instanceof TypeError && /browsingContexts should be string/i.test(e.message)) {
// extract id strings from context objects and retry
} else throw e
} Prevention
- Extract the .context id string from context info objects before subscribing.
- Omit the browsingContexts arg to subscribe globally when per-context filtering is not needed.
- Validate context id arrays with typeof checks before calling.
When it happens
Trigger: Calling bidi.subscribe(events, browsingContexts) where browsingContexts is a number, object, null, or an array containing non-string elements (e.g. subscribe('log.entryAdded', window), subscribe('log.entryAdded', [123]), or subscribe('log.entryAdded', [{context:'abc'}])).
Common situations: Passing a context object or wrapper instead of its string id; reusing a variable typed as a number/BigInt context handle; forgetting to extract the .context field from a BrowsingContextInfo object before subscribing.
Related errors
- events should be string or string array
- Params must be an instance of AddInterceptParameters. Receiv
- Params must be an instance of ContinueRequestParameters. Rec
- Params must be an instance of ContinueResponseParameters. Re
- Params must be an instance of ProvideResponseParameters. Rec
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/31bd52616af2c1e3.
Report an issue: GitHub.