SeleniumHQ/selenium · error · TypeError
events should be string or string array
Error message
events should be string or string array
What it means
Thrown by the BiDi session.subscribe() method when the events argument is neither a string nor an array of strings. The library wraps the argument with an internal toArray() helper (which tolerates undefined and single values), then checks that every element is a string before sending the session.subscribe WebDriver BiDi command. A non-string element makes the protocol payload invalid, so the client rejects it before the network round-trip.
Source
Thrown at javascript/selenium-webdriver/bidi/index.js:255
async subscribe(events, browsingContexts) {
function toArray(arg) {
if (arg === undefined) {
return []
}
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)
}View on GitHub (pinned to aa36b38e69)
Solutions
- Ensure every entry in the events argument is a string; pass either a single event name string or an array of event-name strings (e.g. subscribe('log.entryAdded') or subscribe(['log.entryAdded','browsingContext.navigationStarted'])).
- If events come from dynamic data, coerce/map them to strings before calling subscribe: events.map(String).
- Use the BiDi event constant objects exported by the library (e.g. NetworkEvent, BrowsingContextEvent) instead of hand-typing names, so values are guaranteed strings.
Example fix
// before
await bidi.subscribe([{ event: 'log.entryAdded' }], contextId)
// after
await bidi.subscribe('log.entryAdded', contextId)
// or an array of strings
await bidi.subscribe(['log.entryAdded', 'browsingContext.navigationStarted'], contextId) Defensive patterns
Strategy: validation
Validate before calling
function assertStringEvents(events) {
const arr = Array.isArray(events) ? events : events === undefined ? [] : [events]
if (arr.length && arr.some((e) => typeof e !== 'string')) {
throw new TypeError('events must be string or string[]')
}
return arr
} Type guard
// events is string | string[] | undefined
function isStringOrStringArray(v) {
if (v === undefined) return true
if (typeof v === 'string') return true
return Array.isArray(v) && v.every((e) => typeof e === 'string')
} Try / catch
try {
await bidi.subscribe(events, contexts)
} catch (e) {
if (e instanceof TypeError && /events should be string/i.test(e.message)) {
// normalize events and retry
} else throw e
} Prevention
- Always use BiDi event constant objects so values are strings.
- Validate dynamic event lists with Array.isArray + typeof checks before subscribe.
- Coerce unknown sources with .map(String) before passing.
When it happens
Trigger: Calling bidi.subscribe(events, browsingContexts) where events is a number, object, boolean, null, or an array containing any non-string element (e.g. subscribe(42), subscribe([{name:'x'}]), or subscribe(['log.entryAdded', 7])).
Common situations: Passing event identifiers from a config object that were not coerced to strings; copying event names from an enum that includes numeric codes; spreading a mixed array built from user input; migrating from a legacy API that accepted different event shapes.
Related errors
- browsingContexts 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/4c7bf8186cf7927f.
Report an issue: GitHub.