pinojs/pino · error · Error

unknown level ${level}

Error message

unknown level ${level}

What it means

The browser logger's setLevel (browser.js:190) throws when assigned a level that is not 'silent' and has no entry in logger.levels.values. Only levels registered on the logger instance (default or custom) are accepted.

Source

Thrown at browser.js:190

      this._logEvent.bindings.push(newBindings)
    }
    // reassigning the level rebuilds the log functions so the updated
    // bindings are prepended to subsequent log calls
    this.level = this._level
  }

  if (transmit) logger._logEvent = createLogEventShape()

  function getLevelVal () {
    return levelToValue(this.level, this)
  }

  function getLevel () {
    return this._level
  }
  function setLevel (level) {
    if (level !== 'silent' && !this.levels.values[level]) {
      throw Error('unknown level ' + level)
    }
    this._level = level

    set(this, setOpts, logger, 'error') // <-- must stay first
    set(this, setOpts, logger, 'fatal')
    set(this, setOpts, logger, 'warn')
    set(this, setOpts, logger, 'info')
    set(this, setOpts, logger, 'debug')
    set(this, setOpts, logger, 'trace')

    customLevels.forEach((level) => {
      set(this, setOpts, logger, level)
    })
  }

  function child (setOpts, bindings, childOptions) {
    if (!bindings) {
      throw new Error('missing bindings for child Pino')

View on GitHub (pinned to 5aa62305c5)

Solutions

  1. Use a valid pino level: trace, debug, info, warn, error, fatal, or silent
  2. Register custom levels: pino({ customLevels: { verbose: 25 } })
  3. Trim/normalize the level string before assigning: level.trim().toLowerCase()

Example fix

// before
logger.level = 'verbose';
// after
const logger = pino({ customLevels: { verbose: 25 } });
logger.level = 'verbose';
Defensive patterns

Strategy: validation

Validate before calling

function safeSetLevel(logger, level) {
  const l = String(level).trim().toLowerCase();
  if (l !== 'silent' && !(l in logger.levels.values)) {
    throw new Error(`unknown level: ${level}`);
  }
  logger.level = l;
}

Type guard

function isKnownLevel(logger, level) {
  return level === 'silent' || typeof logger.levels.values[level] === 'number';
}

Try / catch

try { logger.level = cfgLevel; } catch (e) { if (/unknown level/.test(e.message)) { logger.level = 'info'; console.warn(e.message); } else { throw e; } }

Prevention

When it happens

Trigger: logger.level = 'verbose' or logger.setLevel('trace ') (trailing space) where 'verbose' isn't a registered pino level and no customLevels define it.

Common situations: Using level names from other logging libraries (winston's 'verbose'/'silly'); typos or casing issues ('TRACE'); reading the level from user config or env without validating against known levels.

Related errors


AI-assisted analysis of pinojs/pino@5aa62305c5 (2026-09-02). Data as JSON: /api/errors/37630a5d7fafb1a3. Report an issue: GitHub.