{"record":{"id":"66c95e9b577120da","repo":"pinojs/pino","slug":"pino-transport-multi-targets-level-formatter","errorCode":"PINO_TRANSPORT_MULTI_TARGETS_LEVEL_FORMATTER","errorMessage":"custom formatters.level detected with multiple transport targets/pipelines; ensure logs include a numeric \"level\" field or they may be dropped","messagePattern":"custom formatters\\.level detected with multiple transport targets/pipelines; ensure logs include a numeric \"level\" field or they may be dropped","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pino.js","lineNumber":188,"sourceCode":"\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\n    }\n\n    if (!ok) {\n      process.emitWarning(\n        'custom formatters.level detected with multiple transport targets/pipelines; ensure logs include a numeric \"level\" field or they may be dropped',\n        { code: 'PINO_TRANSPORT_MULTI_TARGETS_LEVEL_FORMATTER' }\n      )\n    }\n  }\n\n  if (typeof stream.emit === 'function') {\n    stream.emit('message', { code: 'PINO_CONFIG', config: { levels, messageKey, errorKey } })\n  }\n\n  assertLevelComparison(levelComparison)\n  const levelCompFunc = genLevelComparison(levelComparison)\n\n  Object.assign(instance, {\n    levels,\n    [levelCompSym]: levelCompFunc,\n    [useOnlyCustomLevelsSym]: useOnlyCustomLevels,\n    [streamSym]: stream,\n    [timeSym]: time,\n    [timeSliceIndexSym]: timeSliceIndex,","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/pinojs/pino/blob/5aa62305c57709ebd6f6b7c328e8830eeb29b297/pino.js#L170-L206","documentation":"This is a process warning (not a throw) emitted by pino() (pino.js:188, code PINO_TRANSPORT_MULTI_TARGETS_LEVEL_FORMATTER). When multiple transport targets are used and a custom formatters.level does not output a numeric level field, worker-thread transports may drop logs because they cannot compare non-numeric levels against their configured thresholds.","triggerScenarios":"pino({ transport: { targets: [...] }, formatters: { level: (label, number) => ({ level: label }) } }) — custom level formatter returning a string label while multiple targets/pipelines are configured.","commonSituations":"Customizing level output to human-readable labels while also adding multiple destinations (file + pretty console); upgrading to multi-target transports without revisiting legacy formatters.","solutions":["Make formatters.level include the numeric level: (label, number) => ({ level: number })","Return both fields, e.g. { level: number, levelLabel: label }","Restructure to a single target with a pipeline that adds the label at the presentation layer (e.g. pino-pretty)"],"exampleFix":"// before\nformatters: { level: (label) => ({ level: label }) }\n// after\nformatters: { level: (label, number) => ({ level: number, levelLabel: label }) }","handlingStrategy":"validation","validationCode":"const hasMultiTargets = !!(opts.transport && (Array.isArray(opts.transport.targets) || opts.transport.target));\nif (hasMultiTargets && opts.formatters && typeof opts.formatters.level === 'function') {\n  // ensure the formatter emits a numeric level\n}","typeGuard":"function emitsNumericLevel(formatter) {\n  const out = formatter('info', 30);\n  return typeof out.level === 'number';\n}","tryCatchPattern":"process.on('warning', (w) => { if (w.code === 'PINO_TRANSPORT_MULTI_TARGETS_LEVEL_FORMATTER') { /* fix formatters.level to emit numeric level */ } });","preventionTips":["Keep formatters.level returning { level: number } and add labels at the transport/pretty layer","Test logger output shape whenever combining formatters with transports","Listen for process warnings in CI to catch this during builds"],"tags":["logging","pino","transport","formatters"],"backgroundTag":"log-level-formatter-mismatch","analyzedSha":"5aa62305c57709ebd6f6b7c328e8830eeb29b297","analyzedAt":"2026-09-02T22:05:21.418Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}