{"record":{"id":"72396cc0b4baae40","repo":"pinojs/pino","slug":"pre-existing-level-values-cannot-be-used-for-new-l","errorCode":null,"errorMessage":"pre-existing level values cannot be used for new levels","messagePattern":"pre-existing level values cannot be used for new levels","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/levels.js","lineNumber":205,"sourceCode":"\n  const labels = Object.assign(\n    Object.create(Object.prototype, { silent: { value: Infinity } }),\n    useOnlyCustomLevels ? null : DEFAULT_LEVELS,\n    customLevels\n  )\n  if (!(defaultLevel in labels)) {\n    throw Error(`default level:${defaultLevel} must be included in custom levels`)\n  }\n}\n\nfunction assertNoLevelCollisions (levels, customLevels) {\n  const { labels, values } = levels\n  for (const k in customLevels) {\n    if (k in values) {\n      throw Error('levels cannot be overridden')\n    }\n    if (customLevels[k] in labels) {\n      throw Error('pre-existing level values cannot be used for new levels')\n    }\n  }\n}\n\n/**\n * Validates whether `levelComparison` is correct\n *\n * @throws Error\n * @param {SORTING_ORDER | Function} levelComparison - value to validate\n * @returns\n */\nfunction assertLevelComparison (levelComparison) {\n  if (typeof levelComparison === 'function') {\n    return\n  }\n\n  if (typeof levelComparison === 'string' && Object.values(SORTING_ORDER).includes(levelComparison)) {\n    return","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/pinojs/pino/blob/5aa62305c57709ebd6f6b7c328e8830eeb29b297/lib/levels.js#L187-L223","documentation":"The second collision check in assertNoLevelCollisions: it throws when a customLevels key's numeric VALUE already belongs to an existing level label in the parent. Two different names sharing one numeric value would make level filtering ambiguous, so pino rejects it.","triggerScenarios":"logger.child({}, { customLevels: { notice: 30 } }) where 30 is 'info' in the parent; customLevels: { verbose: 20 } on a parent where 20 is 'debug'.","commonSituations":"Assigning sequential numbers (10, 20, 30...) to custom levels without realizing defaults already occupy 10–60; merging level tables from two services that use overlapping numeric ranges.","solutions":["Pick a numeric value not used by any existing level (check Object.values(logger.levels.values)).","Use values outside the default range, e.g. 25, 35, 45, or above 60, ensuring uniqueness.","Rename/remap the custom level value in your shared config so it does not clash.","Validate the customLevels object programmatically before calling .child()."],"exampleFix":"// before\nconst child = logger.child({}, { customLevels: { notice: 30 } }) // 30 == info\n// after\nconst child = logger.child({}, { customLevels: { notice: 35 } })","handlingStrategy":"validation","validationCode":"function assertUniqueLevelValues(parent, customLevels = {}) {\n  const used = new Set(Object.values(parent.levels.values))\n  for (const [k, v] of Object.entries(customLevels)) {\n    if (used.has(v)) throw new Error(`custom level '${k}' value ${v} already in use`)\n  }\n}","typeGuard":"function hasUniqueLevelValues(parent, customLevels) {\n  const used = new Set(Object.values(parent.levels.values))\n  return Object.values(customLevels || {}).every(v => !used.has(v))\n}","tryCatchPattern":"try {\n  child = logger.child(bindings, { customLevels })\n} catch (e) {\n  if (e.message === 'pre-existing level values cannot be used for new levels') {\n    console.error('Custom level numbers collide with existing levels:', logger.levels.values)\n    throw e\n  }\n  throw e\n}","preventionTips":["Pick custom level values outside the default 10-60 range and keep them in a shared constant.","Check Object.values(logger.levels.values) before assigning numeric values.","Avoid auto-generated sequential numbers that overlap defaults.","Document the numeric level registry for your team to prevent duplicates."],"tags":["configuration","logging","child-logger"],"backgroundTag":"log-level-collision","analyzedSha":"5aa62305c57709ebd6f6b7c328e8830eeb29b297","analyzedAt":"2026-09-02T22:05:21.418Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}