{"record":{"id":"11840f9f4751fa14","repo":"pinojs/pino","slug":"customlevels-is-required-if-useonlycustomlevels-is","errorCode":null,"errorMessage":"customLevels is required if useOnlyCustomLevels is set true","messagePattern":"customLevels is required if useOnlyCustomLevels is set true","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pino.js","lineNumber":164,"sourceCode":"    [stringifySafeSym]: stringifySafe,\n    [formattersSym]: allFormatters\n  })\n\n  let chindings = ''\n  if (base !== null) {\n    if (name === undefined) {\n      chindings = coreChindings(base)\n    } else {\n      chindings = coreChindings(Object.assign({}, base, { name }))\n    }\n  }\n\n  const time = (timestamp instanceof Function)\n    ? timestamp\n    : (timestamp ? epochTime : nullTime)\n  const timeSliceIndex = time().indexOf(':') + 1\n\n  if (useOnlyCustomLevels && !customLevels) throw Error('customLevels is required if useOnlyCustomLevels is set true')\n  if (mixin && typeof mixin !== 'function') throw Error(`Unknown mixin type \"${typeof mixin}\" - expected \"function\"`)\n  if (msgPrefix && typeof msgPrefix !== 'string') throw Error(`Unknown msgPrefix type \"${typeof msgPrefix}\" - expected \"string\"`)\n\n  assertDefaultLevelFound(level, customLevels, useOnlyCustomLevels)\n  const levels = mappings(customLevels, useOnlyCustomLevels)\n\n  if (stream && stream[transportUsesMultistreamSym] === true) {\n    let sampleLabel = typeof level === 'string' ? level : undefined\n    if (!sampleLabel || levels[sampleLabel] === undefined) {\n      sampleLabel = Object.keys(levels)[0]\n    }\n    const sampleNumber = levels[sampleLabel]\n    let ok = false\n    try {\n      const formatted = formatters.level(sampleLabel, sampleNumber)\n      ok = formatted && typeof formatted === 'object' && formatted.level === sampleNumber\n    } catch {\n      ok = false","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/pinojs/pino/blob/5aa62305c57709ebd6f6b7c328e8830eeb29b297/pino.js#L146-L182","documentation":"useOnlyCustomLevels: true tells Pino to recognize ONLY the levels defined in customLevels, discarding default levels. Without customLevels there would be zero levels, so Pino throws at logger creation.","triggerScenarios":"Calling pino({ useOnlyCustomLevels: true }) or pino({ level: 'mylevel', useOnlyCustomLevels: true }) without a customLevels map.","commonSituations":"Copy-pasting custom-level examples and enabling useOnlyCustomLevels before defining customLevels; enabling the flag in shared config where customLevels is conditionally provided; typos like customLevel (singular).","solutions":["Add a customLevels object, e.g. customLevels: { foo: 10, bar: 20 }.","Or remove useOnlyCustomLevels if you want default levels merged with custom ones.","Verify the option spelling: customLevels (plural), defined as { name: number } with numbers > 0."],"exampleFix":"// before\nconst logger = pino({ useOnlyCustomLevels: true })\n// after\nconst logger = pino({ useOnlyCustomLevels: true, customLevels: { trace2: 15, debug2: 25 } })","handlingStrategy":"validation","validationCode":"function validateCustomLevels(opts) {\n  if (opts && opts.useOnlyCustomLevels && !(opts.customLevels && Object.keys(opts.customLevels).length > 0)) {\n    throw new TypeError('useOnlyCustomLevels: true requires a non-empty customLevels map')\n  }\n  return true\n}","typeGuard":"const hasCustomLevels = (opts) => Boolean(opts && opts.customLevels && typeof opts.customLevels === 'object' && Object.keys(opts.customLevels).length > 0)","tryCatchPattern":"try {\n  const logger = pino(opts)\n} catch (err) {\n  if (err.message.startsWith('customLevels is required if useOnlyCustomLevels')) {\n    logger = pino({ ...opts, customLevels: { info: 30, error: 50 } })\n  } else throw err\n}","preventionTips":["Never set useOnlyCustomLevels without also defining customLevels","Keep customLevels and useOnlyCustomLevels adjacent in the options object to avoid conditional omission","Type the options object so useOnlyCustomLevels: true requires customLevels (discriminated union)"],"tags":["pino","configuration","levels","validation"],"backgroundTag":"missing-required-option","analyzedSha":"5aa62305c57709ebd6f6b7c328e8830eeb29b297","analyzedAt":"2026-09-02T22:05:21.418Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}