pinojs/pino · error · Error

prettyPrint option is no longer supported, see the pino-pret

Error message

prettyPrint option is no longer supported, see the pino-pretty package (https://github.com/pinojs/pino-pretty)

What it means

The prettyPrint option was removed in pino v7+. createArgsNormalizer (lib/tools.js:356) rejects it outright and directs users to the standalone pino-pretty package, because pretty-printing is now handled as a transport rather than an in-process option.

Source

Thrown at lib/tools.js:356

      if (opts.transport instanceof SonicBoom || opts.transport.writable || opts.transport._writableState) {
        throw Error('option.transport do not allow stream, please pass to option directly. e.g. pino(transport)')
      }
      if (opts.transport.targets && opts.transport.targets.length && opts.formatters && typeof opts.formatters.level === 'function') {
        throw Error('option.transport.targets do not allow custom level formatters')
      }

      let customLevels
      if (opts.customLevels) {
        customLevels = opts.useOnlyCustomLevels ? opts.customLevels : Object.assign({}, opts.levels, opts.customLevels)
      }
      stream = transport({ caller, ...opts.transport, levels: customLevels })
    }
    opts = Object.assign({}, defaultOptions, opts)
    opts.serializers = Object.assign(Object.create(null), defaultOptions.serializers, opts.serializers)
    opts.formatters = Object.assign({}, defaultOptions.formatters, opts.formatters)

    if (opts.prettyPrint) {
      throw new Error('prettyPrint option is no longer supported, see the pino-pretty package (https://github.com/pinojs/pino-pretty)')
    }

    const { enabled, onChild } = opts
    if (enabled === false) opts.level = 'silent'
    if (!onChild) opts.onChild = noop
    if (!stream) {
      if (!hasBeenTampered(process.stdout)) {
        // If process.stdout.fd is undefined, it means that we are running
        // in a worker thread. Let's assume we are logging to file descriptor 1.
        stream = buildSafeSonicBoom({ fd: process.stdout.fd || 1 })
      } else {
        stream = process.stdout
      }
    }
    return { opts, stream }
  }
}

View on GitHub (pinned to 5aa62305c5)

Solutions

  1. Remove the prettyPrint option and use a transport: pino({ transport: { target: 'pino-pretty' } })
  2. Pipe output through the pino-pretty CLI: node app.js | pino-pretty
  3. Pin pino v6 only if you cannot migrate (not recommended)

Example fix

// before
const logger = pino({ prettyPrint: { colorize: true } });
// after
const logger = pino({ transport: { target: 'pino-pretty', options: { colorize: true } } });
Defensive patterns

Strategy: validation

Validate before calling

function assertNoPrettyPrint(opts = {}) {
  if ('prettyPrint' in opts) {
    throw new Error('prettyPrint was removed in pino v7; use transport with pino-pretty');
  }
}

Type guard

function usesLegacyPrettyPrint(opts) { return typeof opts === 'object' && opts !== null && 'prettyPrint' in opts; }

Try / catch

try { logger = pino(opts); } catch (e) { if (/prettyPrint option is no longer supported/.test(e.message)) { logger = pino({ transport: { target: 'pino-pretty' } }); } else { throw e; } }

Prevention

When it happens

Trigger: Passing pino({ prettyPrint: true }) or any truthy prettyPrint object to pino() or pino.destination().

Common situations: Upgrading from pino v6 or earlier to v7+; copying old tutorials or config; enabling pretty logs in production code that was written against the legacy API.

Related errors


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