{"record":{"id":"bac251da3fff31f3","repo":"pinojs/pino","slug":"pino-redact-must-contain-an-array-of-strings","errorCode":null,"errorMessage":"pino – redact must contain an array of strings","messagePattern":"pino – redact must contain an array of strings","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browser.js","lineNumber":16,"sourceCode":"'use strict'\n\nconst format = require('quick-format-unescaped')\nconst Redact = require('@pinojs/redact')\n\nmodule.exports = pino\n\nconst CENSOR = '[Redacted]'\n\nfunction handleRedactOpts (opts) {\n  if (Array.isArray(opts)) {\n    return { paths: opts, censor: CENSOR }\n  }\n  const { paths, censor = CENSOR, remove } = opts\n  if (!Array.isArray(paths)) {\n    throw Error('pino – redact must contain an array of strings')\n  }\n  return { paths, censor: remove ? undefined : censor, remove }\n}\n\nfunction buildRedactFn (redact) {\n  if (!redact) return null\n  const { paths, censor, remove } = handleRedactOpts(redact)\n  return Redact({\n    paths,\n    censor,\n    remove,\n    serialize: false\n  })\n}\n\nconst _console = pfGlobalThisOrFallback().console || {}\nconst stdSerializers = {\n  mapHttpRequest: mock,","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/pinojs/pino/blob/5aa62305c57709ebd6f6b7c328e8830eeb29b297/browser.js#L1-L34","documentation":"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.","triggerScenarios":"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).","commonSituations":"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: { ... }.","solutions":["Pass an array: redact: ['secret', 'password']","If using the object form, supply paths as an array: redact: { paths: ['req.headers.authorization'], censor: '[REDACTED]' }","Validate option shapes coming from config files before constructing the logger"],"exampleFix":"// before\npino({ redact: 'password' });\n// after\npino({ redact: ['password'] });","handlingStrategy":"type-guard","validationCode":"function assertValidRedact(redact) {\n  const paths = Array.isArray(redact) ? redact : redact && redact.paths;\n  if (!Array.isArray(paths)) throw new Error('redact must be an array or { paths: [...] }');\n}","typeGuard":"function hasRedactPaths(r) {\n  return Array.isArray(r) || (typeof r === 'object' && r !== null && Array.isArray(r.paths));\n}","tryCatchPattern":"try { logger = pino({ redact }); } catch (e) { if (/redact must contain an array/.test(e.message)) { logger = pino({ redact: [redact].flat() }); } else { throw e; } }","preventionTips":["Wrap single path strings in an array before passing to redact","Use TypeScript: redact?: string[] | { paths: string[]; censor?: string; remove?: boolean }","Validate config-file redact values at startup"],"tags":["logging","pino","browser","redaction","validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"5aa62305c57709ebd6f6b7c328e8830eeb29b297","analyzedAt":"2026-09-02T22:05:21.418Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}