pinojs/pino · error · Error

pino – redact must contain an array of strings

Error message

pino – redact must contain an array of strings

What it means

handleRedactOpts (browser.js:16) validates the redact option in the browser build. When redact is an object rather than an array, its paths property must be an array of strings; otherwise this Error is thrown because the redaction engine cannot compute paths to censor.

Source

Thrown at browser.js:16

'use strict'

const format = require('quick-format-unescaped')
const Redact = require('@pinojs/redact')

module.exports = pino

const CENSOR = '[Redacted]'

function handleRedactOpts (opts) {
  if (Array.isArray(opts)) {
    return { paths: opts, censor: CENSOR }
  }
  const { paths, censor = CENSOR, remove } = opts
  if (!Array.isArray(paths)) {
    throw Error('pino – redact must contain an array of strings')
  }
  return { paths, censor: remove ? undefined : censor, remove }
}

function buildRedactFn (redact) {
  if (!redact) return null
  const { paths, censor, remove } = handleRedactOpts(redact)
  return Redact({
    paths,
    censor,
    remove,
    serialize: false
  })
}

const _console = pfGlobalThisOrFallback().console || {}
const stdSerializers = {
  mapHttpRequest: mock,

View on GitHub (pinned to 5aa62305c5)

Solutions

  1. Pass an array: redact: ['secret', 'password']
  2. If using the object form, supply paths as an array: redact: { paths: ['req.headers.authorization'], censor: '[REDACTED]' }
  3. Validate option shapes coming from config files before constructing the logger

Example fix

// before
pino({ redact: 'password' });
// after
pino({ redact: ['password'] });
Defensive patterns

Strategy: type-guard

Validate before calling

function assertValidRedact(redact) {
  const paths = Array.isArray(redact) ? redact : redact && redact.paths;
  if (!Array.isArray(paths)) throw new Error('redact must be an array or { paths: [...] }');
}

Type guard

function hasRedactPaths(r) {
  return Array.isArray(r) || (typeof r === 'object' && r !== null && Array.isArray(r.paths));
}

Try / catch

try { logger = pino({ redact }); } catch (e) { if (/redact must contain an array/.test(e.message)) { logger = pino({ redact: [redact].flat() }); } else { throw e; } }

Prevention

When it happens

Trigger: pino({ redact: 'secret' }) (a string not wrapped in an array), or pino({ redact: { censor: 'X' } }) missing paths, or redact: { paths: 'a.b' } (string instead of array).

Common situations: Confusing the two redact shapes: array shorthand vs object form with paths/censor/remove; copying server-side config where redact was a single path string; typos like paths: { ... }.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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