{"record":{"id":"31bd52616af2c1e3","repo":"SeleniumHQ/selenium","slug":"browsingcontexts-should-be-string-or-string-array","errorCode":null,"errorMessage":"browsingContexts should be string or string array","messagePattern":"browsingContexts should be string or string array","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"javascript/selenium-webdriver/bidi/index.js","lineNumber":259,"sourceCode":"      }\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  }\n\n  /**\n   * Unsubscribe to events\n   * @param events","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/javascript/selenium-webdriver/bidi/index.js#L241-L277","documentation":"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.","triggerScenarios":"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'}])).","commonSituations":"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.","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."],"exampleFix":"// before\nconst info = await browsingContext.create(contextDescriptor)\nawait bidi.subscribe('log.entryAdded', info) // info is an object\n\n// after\nawait bidi.subscribe('log.entryAdded', info.context) // pass the id string","handlingStrategy":"validation","validationCode":"function assertStringContexts(contexts) {\n  const arr = Array.isArray(contexts) ? contexts : contexts === undefined ? [] : [contexts]\n  if (arr.length && arr.some((c) => typeof c !== 'string')) {\n    throw new TypeError('browsingContexts must be string or string[]')\n  }\n  return arr\n}","typeGuard":"function isContextIdList(v) {\n  if (v === undefined) return true\n  if (typeof v === 'string') return true\n  return Array.isArray(v) && v.every((c) => typeof c === 'string')\n}","tryCatchPattern":"try {\n  await bidi.subscribe(events, contexts)\n} catch (e) {\n  if (e instanceof TypeError && /browsingContexts should be string/i.test(e.message)) {\n    // extract id strings from context objects and retry\n  } else throw e\n}","preventionTips":["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."],"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"}