videojs/video.js · error · Error

"${lvl}" in not a valid log level

Error message

"${lvl}" in not a valid log level

What it means

Thrown by log.level(lvl) when lvl is a string that is not a key of log.levels. Valid level keys are 'all', 'off', 'debug', 'info', 'warn', 'error' (plus the meta 'DEFAULT'). Passing undefined (or any non-string) acts as a getter and does not throw. Note the message has a typo ('in not' instead of 'is not').

Source

Thrown at src/js/utils/create-logger.js:198

    DEFAULT: level
  };

  /**
   * Get or set the current logging level.
   *
   * If a string matching a key from {@link module:log.levels} is provided, acts
   * as a setter.
   *
   * @param  {'all'|'debug'|'info'|'warn'|'error'|'off'} [lvl]
   *         Pass a valid level to set a new logging level.
   *
   * @return {string}
   *         The current logging level.
   */
  log.level = (lvl) => {
    if (typeof lvl === 'string') {
      if (!log.levels.hasOwnProperty(lvl)) {
        throw new Error(`"${lvl}" in not a valid log level`);
      }
      level = lvl;
    }
    return level;
  };

  /**
   * Returns an array containing everything that has been logged to the history.
   *
   * This array is a shallow clone of the internal history record. However, its
   * contents are _not_ cloned; so, mutating objects inside this array will
   * mutate them in history.
   *
   * @return {Array}
   */
  log.history = () => history ? [].concat(history) : [];

  /**

View on GitHub (pinned to c3a7e0e6d2)

Solutions

  1. Use one of the allowed levels: 'all', 'off', 'debug', 'info', 'warn', 'error'.
  2. Validate an env/config-derived level against Object.keys(videojs.log.levels) before setting.
  3. Lowercase the input and fall back to a sane default if unknown.

Example fix

// before
videojs.log.level('trace');
// after
videojs.log.level('debug');
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = Object.keys(videojs.log.levels);
function safeSetLevel(lvl) {
  const norm = String(lvl).toLowerCase();
  if (!ALLOWED.includes(norm)) {
    throw new TypeError(`log level must be one of ${ALLOWED.join(', ')}, got: ${lvl}`);
  }
  return videojs.log.level(norm);
}

Type guard

function isValidLogLevel(lvl) {
  return typeof lvl === 'string' && Object.prototype.hasOwnProperty.call(videojs.log.levels, lvl.toLowerCase());
}

Try / catch

try {
  videojs.log.level(lvl);
} catch (err) {
  if (/valid log level/.test(err.message)) {
    videojs.log.level('info');
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling videojs.log.level('trace'), videojs.log.level('verbose'), or videojs.log.level('fatal') - any string outside the allowed set. Common when the level comes from an env var or config without validation.

Common situations: Migrating from another logger (winston, loglevel, pino) whose level names differ; reading the level from a QUERY_STRING/ENV/config file that uses 'trace'/'verbose'/'silent'; case-sensitivity issues ('Error' vs 'error').

Related errors


AI-assisted analysis of videojs/video.js@c3a7e0e6d2 (2026-08-13). Data as JSON: /api/errors/335cd5207667117b. Report an issue: GitHub.