{"record":{"id":"4c7bf8186cf7927f","repo":"SeleniumHQ/selenium","slug":"events-should-be-string-or-string-array","errorCode":null,"errorMessage":"events should be string or string array","messagePattern":"events should be string or string array","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"javascript/selenium-webdriver/bidi/index.js","lineNumber":255,"sourceCode":"  async subscribe(events, browsingContexts) {\n    function toArray(arg) {\n      if (arg === undefined) {\n        return []\n      }\n\n      return Array.isArray(arg) ? [...arg] : [arg]\n    }\n\n    const eventsArray = toArray(events)\n    const contextsArray = toArray(browsingContexts)\n\n    const params = {\n      method: 'session.subscribe',\n      params: {},\n    }\n\n    if (eventsArray.length && eventsArray.some((event) => typeof event !== 'string')) {\n      throw new TypeError('events should be string or string array')\n    }\n\n    if (contextsArray.length && contextsArray.some((context) => typeof context !== 'string')) {\n      throw new TypeError('browsingContexts should be string or string array')\n    }\n\n    if (eventsArray.length) {\n      params.params.events = eventsArray\n    }\n\n    if (contextsArray.length) {\n      params.params.contexts = contextsArray\n    }\n\n    this.events.push(...eventsArray)\n\n    await this.send(params)\n  }","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/javascript/selenium-webdriver/bidi/index.js#L237-L273","documentation":"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.","triggerScenarios":"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])).","commonSituations":"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.","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."],"exampleFix":"// before\nawait bidi.subscribe([{ event: 'log.entryAdded' }], contextId)\n\n// after\nawait bidi.subscribe('log.entryAdded', contextId)\n// or an array of strings\nawait bidi.subscribe(['log.entryAdded', 'browsingContext.navigationStarted'], contextId)","handlingStrategy":"validation","validationCode":"function assertStringEvents(events) {\n  const arr = Array.isArray(events) ? events : events === undefined ? [] : [events]\n  if (arr.length && arr.some((e) => typeof e !== 'string')) {\n    throw new TypeError('events must be string or string[]')\n  }\n  return arr\n}","typeGuard":"// events is string | string[] | undefined\nfunction isStringOrStringArray(v) {\n  if (v === undefined) return true\n  if (typeof v === 'string') return true\n  return Array.isArray(v) && v.every((e) => typeof e === 'string')\n}","tryCatchPattern":"try {\n  await bidi.subscribe(events, contexts)\n} catch (e) {\n  if (e instanceof TypeError && /events should be string/i.test(e.message)) {\n    // normalize events and retry\n  } else throw e\n}","preventionTips":["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."],"tags":["bidi","session","subscribe","type-validation","javascript"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}