{"record":{"id":"6619d71efd8d7b7a","repo":"pinojs/pino","slug":"levels-cannot-be-overridden","errorCode":null,"errorMessage":"levels cannot be overridden","messagePattern":"levels cannot be overridden","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/levels.js","lineNumber":202,"sourceCode":"    }\n    return\n  }\n\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  }","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/pinojs/pino/blob/5aa62305c57709ebd6f6b7c328e8830eeb29b297/lib/levels.js#L184-L220","documentation":"assertNoLevelCollisions runs when creating a child logger with customLevels. It throws 'levels cannot be overridden' when a customLevels key already exists as a level name in the parent's values map — pino forbids redefining an existing level name on a child.","triggerScenarios":"logger.child({}, { customLevels: { info: 25 } }) — 'info' is already a built-in level; logger.child(bindings, { customLevels: { debug: 15 } }) on a parent that already has debug.","commonSituations":"Trying to remap a standard level's value for a submodule's child logger; merging user-supplied level config that happens to contain standard level names.","solutions":["Rename the custom level to a non-conflicting name (e.g. 'info2' or 'notice').","Remove the conflicting key from the child's customLevels and inherit the parent level.","If the level must differ, create a brand-new root logger instead of a child.","Filter config-supplied custom levels against logger.levels.values before passing them."],"exampleFix":"// before\nconst child = logger.child({}, { customLevels: { info: 25 } })\n// after\nconst child = logger.child({}, { customLevels: { notice: 25 } })","handlingStrategy":"validation","validationCode":"function safeChildCustomLevels(parent, customLevels = {}) {\n  const conflicts = Object.keys(customLevels).filter(k => k in parent.levels.values)\n  if (conflicts.length) throw new Error(`child customLevels override existing levels: ${conflicts}`)\n  return customLevels\n}\nconst child = logger.child({}, { customLevels: safeChildCustomLevels(logger, cfg.customLevels) })","typeGuard":"function hasNoLevelNameConflicts(parent, customLevels) {\n  return Object.keys(customLevels || {}).every(k => !(k in parent.levels.values))\n}","tryCatchPattern":"try {\n  child = logger.child(bindings, { customLevels })\n} catch (e) {\n  if (e.message === 'levels cannot be overridden') {\n    child = logger.child(bindings) // fall back to inherited levels\n  } else throw e\n}","preventionTips":["Never include standard level names (trace..fatal, silent) in child customLevels.","Prefix custom level names with a module tag, e.g. 'audit'.","Sanitize user/config-provided level maps before passing to .child().","Centralize child-logger creation in a helper that checks collisions once."],"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"}