SeleniumHQ/selenium · error · TypeError

not a string or number

Error message

not a string or number

What it means

Thrown by getLevel() (logging.js) when its argument is neither a string nor a number — e.g. an object, array, undefined, boolean, or null. The function converts a level name or numeric value to a Level; anything else is a programming/type error. Returns Level.ALL for unrecognized but correctly-typed inputs, so this throw is specifically for wrong types.

Source

Thrown at javascript/selenium-webdriver/lib/logging.js:196

  [Level.FINER.name, Level.FINER],
  [Level.FINEST.name, Level.FINEST],
  [Level.ALL.name, Level.ALL],
])

/**
 * Converts a level name or value to a {@link Level} value. If the name/value
 * is not recognized, {@link Level.ALL} will be returned.
 *
 * @param {(number|string)} nameOrValue The log level name, or value, to
 *     convert.
 * @return {!Level} The converted level.
 */
function getLevel(nameOrValue) {
  if (typeof nameOrValue === 'string') {
    return LEVELS_BY_NAME.get(nameOrValue) || Level.ALL
  }
  if (typeof nameOrValue !== 'number') {
    throw new TypeError('not a string or number')
  }
  for (let level of ALL_LEVELS) {
    if (nameOrValue >= level.value) {
      return level
    }
  }
  return Level.ALL
}

/**
 * Describes a single log entry.
 *
 * @final
 */
class Entry {
  /**
   * @param {(!Level|string|number)} level The entry level.
   * @param {string} message The log message.

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Pass a string name ('INFO') or a number (800).
  2. Default the argument: getLevel(input ?? 'INFO').
  3. Coerce: getLevel(typeof input === 'number' ? input : String(input)).
  4. Guard upstream with typeof input === 'string' || typeof input === 'number'.

Example fix

// before
const lvl = logging.getLevel(config.logging); // config.logging is an object

// after
const lvl = logging.getLevel(config.logging?.level ?? 'INFO');
Defensive patterns

Strategy: type-guard

Validate before calling

function safeGetLevel(nameOrValue) {
  if (typeof nameOrValue !== 'string' && typeof nameOrValue !== 'number') {
    return logging.Level.ALL; // or throw
  }
  return logging.getLevel(nameOrValue);
}

Type guard

function isLevelNameOrValue(x) {
  return typeof x === 'string' || typeof x === 'number';
}

Try / catch

try {
  level = logging.getLevel(input);
} catch (e) {
  if (e instanceof TypeError && /not a string or number/.test(e.message)) {
    level = logging.Level.ALL;
  } else throw e;
}

Prevention

When it happens

Trigger: getLevel({name:'INFO'}), getLevel(undefined), getLevel(true), getLevel(null). Passing a logger instance or a config object instead of the level field. Note null is typeof 'object' so it hits this branch.

Common situations: Destructuring a config object and passing the whole object instead of a field; default parameter evaluates to undefined when the caller omits the arg; reading a value that may be missing and not defaulting.

Related errors


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