SeleniumHQ/selenium · error · TypeError

input must be a string

Error message

input must be a string

What it means

Thrown by escapeCss() in by.js when the input typeof is not 'string'. This function serializes a CSS identifier per the CSSOM spec and requires a string input. It is used internally by By.css() and available as a public export.

Source

Thrown at javascript/selenium-webdriver/lib/by.js:69

 */
class InvalidCharacterError extends Error {
  constructor() {
    super()
    this.name = this.constructor.name
  }
}

/**
 * Escapes a CSS string.
 * @param {string} css the string to escape.
 * @return {string} the escaped string.
 * @throws {TypeError} if the input value is not a string.
 * @throws {InvalidCharacterError} if the string contains an invalid character.
 * @see https://drafts.csswg.org/cssom/#serialize-an-identifier
 */
function escapeCss(css) {
  if (typeof css !== 'string') {
    throw new TypeError('input must be a string')
  }
  let ret = ''
  const n = css.length
  for (let i = 0; i < n; i++) {
    const c = css.charCodeAt(i)
    if (c == 0x0) {
      throw new InvalidCharacterError()
    }

    if (
      (c >= 0x0001 && c <= 0x001f) ||
      c == 0x007f ||
      (i == 0 && c >= 0x0030 && c <= 0x0039) ||
      (i == 1 && c >= 0x0030 && c <= 0x0039 && css.charCodeAt(0) == 0x002d)
    ) {
      ret += '\\' + c.toString(16) + ' '
      continue
    }

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Convert the value to a string first: escapeCss(String(value)).
  2. Validate typeof value === 'string' before calling.
  3. Use template literals to ensure string context: escapeCss(`${value}`).

Example fix

// before
By.css('#' + escapeCss(element.id)) // element.id is a number
// after
By.css('#' + escapeCss(String(element.id)))
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof css !== 'string') {
  throw new TypeError(`escapeCss expects a string, got ${typeof css}`)
}

Type guard

/**
 * @param {*} v
 * @returns {v is string}
 */
function isString(v) {
  return typeof v === 'string'
}

Prevention

When it happens

Trigger: Passing a number (e.g., element.id that is numeric), null, undefined, an object, or a boolean to escapeCss(). Dynamically building a CSS selector with a non-string fragment.

Common situations: Element IDs read from attributes or data that are numbers; null values from failed lookups passed into selector construction; passing a DOM element instead of its ID string.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/58fa64b72211761e. Report an issue: GitHub.