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
- Convert the value to a string first: escapeCss(String(value)).
- Validate typeof value === 'string' before calling.
- 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
- Coerce values with String() before passing to escapeCss().
- Validate typeof before building CSS selectors dynamically.
- Be cautious with numeric IDs — convert them explicitly.
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
- Invalid locator
- Params must be an instance of CookieFilter. Received:'${cook
- Port must be a number. Received:'${port}'
- Capability keys must be strings: ${typeof key}
- Did not know how to convert ${value} into color
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/58fa64b72211761e.
Report an issue: GitHub.