Skip to content

util.inspect() ignores breakLength: Infinity when depth: Infinity is also set in some cases #60475

@Snowflyt

Description

@Snowflyt

Version

v25.1.0

Platform

- Windows: Microsoft Windows NT 10.0.26200.0 x64
- macOS: Darwin MacBook-Pro.local 24.6.0 Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:51 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T8112 arm64
- Linux: Linux myhost 6.8.0-45-generic #45-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux

Subsystem

util

What steps will reproduce the bug?

When util.inspect() is called with both breakLength: Infinity and depth: Infinity, the output unexpectedly contains line breaks in Node.js v25.x.

In contrast:

  • Using only breakLength: Infinity (with default depth) works correctly and produces a single-line output.
  • The issue appears only when depth is explicitly set to Infinity.

This behavior did not occur in Node.js v24.x, so it appears to be a regression.

A minimal reproducible example is provided below.

$ nvm use 24
Now using node v24.11.0 (npm v11.6.1)
$ node
Welcome to Node.js v24.11.0.
Type ".help" for more information.
> const util = require("node:util")
undefined
> util.inspect(util, { breakLength: Infinity })
"{ _errnoException: [Function: _errnoException], _exceptionWithHostPort: [Function: _exceptionWithHostPort], _extend: [Function: deprecated], callbackify: [Function: callbackify], debug: [Function: debuglog], debuglog: [Function: debuglog], deprecate: [Function: deprecate], format: [Function: format], styleText: [Function: styleText], formatWithOptions: [Function: formatWithOptions], getCallSites: [Function: getCallSites], getSystemErrorMap: [Function: getSystemErrorMap], getSystemErrorName: [Function: getSystemErrorName], getSystemErrorMessage: [Function: getSystemErrorMessage], inherits: [Function: inherits], inspect: [Function: inspect] { custom: Symbol(nodejs.util.inspect.custom), colors: [Object: null prototype] { reset: [Array], bold: [Array], dim: [Array], italic: [Array], underline: [Array], blink: [Array], inverse: [Array], hidden: [Array], strikethrough: [Array], doubleunderline: [Array], black: [Array], red: [Array], green: [Array], yellow: [Array], blue: [Array], magenta: [Array], cyan: [Array], white: [Array], bgBlack: [Array], bgRed: [Array], bgGreen: [Array], bgYellow: [Array], bgBlue: [Array], bgMagenta: [Array], bgCyan: [Array], bgWhite: [Array], framed: [Array], overlined: [Array], gray: [Array], redBright: [Array], greenBright: [Array], yellowBright: [Array], blueBright: [Array], magentaBright: [Array], cyanBright: [Array], whiteBright: [Array], bgGray: [Array], bgRedBright: [Array], bgGreenBright: [Array], bgYellowBright: [Array], bgBlueBright: [Array], bgMagentaBright: [Array], bgCyanBright: [Array], bgWhiteBright: [Array] }, styles: [Object: null prototype] { special: 'cyan', number: 'yellow', bigint: 'yellow', boolean: 'yellow', undefined: 'grey', null: 'bold', string: 'green', symbol: 'green', date: 'magenta', regexp: 'red', module: 'underline' }, replDefaults: [Getter/Setter] }, isArray: [Function: deprecated], isDeepStrictEqual: [Function: isDeepStrictEqual], promisify: [Function: promisify] { custom: Symbol(nodejs.util.promisify.custom) }, stripVTControlCharacters: [Function: stripVTControlCharacters], toUSVString: [Function: toUSVString], transferableAbortSignal: [Getter], transferableAbortController: [Getter], aborted: [Getter], types: { isArgumentsObject: [Function (anonymous)], isArrayBuffer: [Function (anonymous)], isAsyncFunction: [Function (anonymous)], isBigIntObject: [Function (anonymous)], isBooleanObject: [Function (anonymous)], isDataView: [Function (anonymous)], isDate: [Function (anonymous)], isExternal: [Function (anonymous)], isGeneratorFunction: [Function (anonymous)], isGeneratorObject: [Function (anonymous)], isMap: [Function (anonymous)], isMapIterator: [Function (anonymous)], isModuleNamespaceObject: [Function (anonymous)], isNativeError: [Function (anonymous)], isNumberObject: [Function (anonymous)], isPromise: [Function (anonymous)], isProxy: [Function (anonymous)], isRegExp: [Function (anonymous)], isSet: [Function (anonymous)], isSetIterator: [Function (anonymous)], isSharedArrayBuffer: [Function (anonymous)], isStringObject: [Function (anonymous)], isSymbolObject: [Function (anonymous)], isWeakMap: [Function (anonymous)], isWeakSet: [Function (anonymous)], isAnyArrayBuffer: [Function (anonymous)], isBoxedPrimitive: [Function (anonymous)], isArrayBufferView: [Function: isView], isTypedArray: [Function: isTypedArray], isUint8Array: [Function: isUint8Array], isUint8ClampedArray: [Function: isUint8ClampedArray], isUint16Array: [Function: isUint16Array], isUint32Array: [Function: isUint32Array], isInt8Array: [Function: isInt8Array], isInt16Array: [Function: isInt16Array], isInt32Array: [Function: isInt32Array], isFloat16Array: [Function: isFloat16Array], isFloat32Array: [Function: isFloat32Array], isFloat64Array: [Function: isFloat64Array], isBigInt64Array: [Function: isBigInt64Array], isBigUint64Array: [Function: isBigUint64Array], isKeyObject: [Function: value], isCryptoKey: [Function: value] }, parseEnv: [Function: parseEnv], parseArgs: [Function: parseArgs], TextDecoder: [class TextDecoder], TextEncoder: [class TextEncoder], MIMEType: [class MIMEType], MIMEParams: [class MIMEParams], diff: [Function: diff], setTraceSigInt: [Function: setTraceSigInt] }"
> util.inspect(util, { breakLength: Infinity, depth: Infinity })
"{ _errnoException: [Function: _errnoException], _exceptionWithHostPort: [Function: _exceptionWithHostPort], _extend: [Function: deprecated], callbackify: [Function: callbackify], debug: [Function: debuglog], debuglog: [Function: debuglog], deprecate: [Function: deprecate], format: [Function: format], styleText: [Function: styleText], formatWithOptions: [Function: formatWithOptions], getCallSites: [Function: getCallSites], getSystemErrorMap: [Function: getSystemErrorMap], getSystemErrorName: [Function: getSystemErrorName], getSystemErrorMessage: [Function: getSystemErrorMessage], inherits: [Function: inherits], inspect: [Function: inspect] { custom: Symbol(nodejs.util.inspect.custom), colors: [Object: null prototype] { reset: [ 0, 0 ], bold: [ 1, 22 ], dim: [ 2, 22 ], italic: [ 3, 23 ], underline: [ 4, 24 ], blink: [ 5, 25 ], inverse: [ 7, 27 ], hidden: [ 8, 28 ], strikethrough: [ 9, 29 ], doubleunderline: [ 21, 24 ], black: [ 30, 39 ], red: [ 31, 39 ], green: [ 32, 39 ], yellow: [ 33, 39 ], blue: [ 34, 39 ], magenta: [ 35, 39 ], cyan: [ 36, 39 ], white: [ 37, 39 ], bgBlack: [ 40, 49 ], bgRed: [ 41, 49 ], bgGreen: [ 42, 49 ], bgYellow: [ 43, 49 ], bgBlue: [ 44, 49 ], bgMagenta: [ 45, 49 ], bgCyan: [ 46, 49 ], bgWhite: [ 47, 49 ], framed: [ 51, 54 ], overlined: [ 53, 55 ], gray: [ 90, 39 ], redBright: [ 91, 39 ], greenBright: [ 92, 39 ], yellowBright: [ 93, 39 ], blueBright: [ 94, 39 ], magentaBright: [ 95, 39 ], cyanBright: [ 96, 39 ], whiteBright: [ 97, 39 ], bgGray: [ 100, 49 ], bgRedBright: [ 101, 49 ], bgGreenBright: [ 102, 49 ], bgYellowBright: [ 103, 49 ], bgBlueBright: [ 104, 49 ], bgMagentaBright: [ 105, 49 ], bgCyanBright: [ 106, 49 ], bgWhiteBright: [ 107, 49 ] }, styles: [Object: null prototype] { special: 'cyan', number: 'yellow', bigint: 'yellow', boolean: 'yellow', undefined: 'grey', null: 'bold', string: 'green', symbol: 'green', date: 'magenta', regexp: 'red', module: 'underline' }, replDefaults: [Getter/Setter] }, isArray: [Function: deprecated], isDeepStrictEqual: [Function: isDeepStrictEqual], promisify: [Function: promisify] { custom: Symbol(nodejs.util.promisify.custom) }, stripVTControlCharacters: [Function: stripVTControlCharacters], toUSVString: [Function: toUSVString], transferableAbortSignal: [Getter], transferableAbortController: [Getter], aborted: [Getter], types: { isArgumentsObject: [Function (anonymous)], isArrayBuffer: [Function (anonymous)], isAsyncFunction: [Function (anonymous)], isBigIntObject: [Function (anonymous)], isBooleanObject: [Function (anonymous)], isDataView: [Function (anonymous)], isDate: [Function (anonymous)], isExternal: [Function (anonymous)], isGeneratorFunction: [Function (anonymous)], isGeneratorObject: [Function (anonymous)], isMap: [Function (anonymous)], isMapIterator: [Function (anonymous)], isModuleNamespaceObject: [Function (anonymous)], isNativeError: [Function (anonymous)], isNumberObject: [Function (anonymous)], isPromise: [Function (anonymous)], isProxy: [Function (anonymous)], isRegExp: [Function (anonymous)], isSet: [Function (anonymous)], isSetIterator: [Function (anonymous)], isSharedArrayBuffer: [Function (anonymous)], isStringObject: [Function (anonymous)], isSymbolObject: [Function (anonymous)], isWeakMap: [Function (anonymous)], isWeakSet: [Function (anonymous)], isAnyArrayBuffer: [Function (anonymous)], isBoxedPrimitive: [Function (anonymous)], isArrayBufferView: [Function: isView], isTypedArray: [Function: isTypedArray], isUint8Array: [Function: isUint8Array], isUint8ClampedArray: [Function: isUint8ClampedArray], isUint16Array: [Function: isUint16Array], isUint32Array: [Function: isUint32Array], isInt8Array: [Function: isInt8Array], isInt16Array: [Function: isInt16Array], isInt32Array: [Function: isInt32Array], isFloat16Array: [Function: isFloat16Array], isFloat32Array: [Function: isFloat32Array], isFloat64Array: [Function: isFloat64Array], isBigInt64Array: [Function: isBigInt64Array], isBigUint64Array: [Function: isBigUint64Array], isKeyObject: [Function: value], isCryptoKey: [Function: value] }, parseEnv: [Function: parseEnv], parseArgs: [Function: parseArgs], TextDecoder: [class TextDecoder], TextEncoder: [class TextEncoder], MIMEType: [class MIMEType], MIMEParams: [class MIMEParams], diff: [Function: diff], setTraceSigInt: [Function: setTraceSigInt] }"
>
$ nvm use 25
Now using node v25.1.0 (npm v11.6.2)
$ node
Welcome to Node.js v25.1.0.
Type ".help" for more information.
> const util = require("node:util")
undefined
> util.inspect(util, { breakLength: Infinity })
"{ _errnoException: [Function: _errnoException], _exceptionWithHostPort: [Function: _exceptionWithHostPort], _extend: [Function: deprecated], callbackify: [Function: callbackify], debug: [Function: debuglog], debuglog: [Function: debuglog], deprecate: [Function: deprecate], format: [Function: format], styleText: [Function: styleText], formatWithOptions: [Function: formatWithOptions], getCallSites: [Function: getCallSites], getSystemErrorMap: [Function: getSystemErrorMap], getSystemErrorName: [Function: getSystemErrorName], getSystemErrorMessage: [Function: getSystemErrorMessage], inherits: [Function: inherits], inspect: [Function: inspect] { custom: Symbol(nodejs.util.inspect.custom), colors: [Object: null prototype] { reset: [Array], bold: [Array], dim: [Array], italic: [Array], underline: [Array], blink: [Array], inverse: [Array], hidden: [Array], strikethrough: [Array], doubleunderline: [Array], black: [Array], red: [Array], green: [Array], yellow: [Array], blue: [Array], magenta: [Array], cyan: [Array], white: [Array], bgBlack: [Array], bgRed: [Array], bgGreen: [Array], bgYellow: [Array], bgBlue: [Array], bgMagenta: [Array], bgCyan: [Array], bgWhite: [Array], framed: [Array], overlined: [Array], gray: [Array], redBright: [Array], greenBright: [Array], yellowBright: [Array], blueBright: [Array], magentaBright: [Array], cyanBright: [Array], whiteBright: [Array], bgGray: [Array], bgRedBright: [Array], bgGreenBright: [Array], bgYellowBright: [Array], bgBlueBright: [Array], bgMagentaBright: [Array], bgCyanBright: [Array], bgWhiteBright: [Array] }, styles: [Object: null prototype] { special: 'cyan', number: 'yellow', bigint: 'yellow', boolean: 'yellow', undefined: 'grey', null: 'bold', string: 'green', symbol: 'green', date: 'magenta', regexp: [Function], module: 'underline' }, replDefaults: [Getter/Setter] }, isArray: [Function: deprecated], isDeepStrictEqual: [Function: isDeepStrictEqual], promisify: [Function: promisify] { custom: Symbol(nodejs.util.promisify.custom) }, stripVTControlCharacters: [Function: stripVTControlCharacters], toUSVString: [Function: toUSVString], transferableAbortSignal: [Getter], transferableAbortController: [Getter], aborted: [Getter], types: { isArgumentsObject: [Function (anonymous)], isArrayBuffer: [Function (anonymous)], isAsyncFunction: [Function (anonymous)], isBigIntObject: [Function (anonymous)], isBooleanObject: [Function (anonymous)], isDataView: [Function (anonymous)], isDate: [Function (anonymous)], isExternal: [Function (anonymous)], isGeneratorFunction: [Function (anonymous)], isGeneratorObject: [Function (anonymous)], isMap: [Function (anonymous)], isMapIterator: [Function (anonymous)], isModuleNamespaceObject: [Function (anonymous)], isNativeError: [Function (anonymous)], isNumberObject: [Function (anonymous)], isPromise: [Function (anonymous)], isProxy: [Function (anonymous)], isRegExp: [Function (anonymous)], isSet: [Function (anonymous)], isSetIterator: [Function (anonymous)], isSharedArrayBuffer: [Function (anonymous)], isStringObject: [Function (anonymous)], isSymbolObject: [Function (anonymous)], isWeakMap: [Function (anonymous)], isWeakSet: [Function (anonymous)], isAnyArrayBuffer: [Function (anonymous)], isBoxedPrimitive: [Function (anonymous)], isArrayBufferView: [Function: isView], isTypedArray: [Function: isTypedArray], isUint8Array: [Function: isUint8Array], isUint8ClampedArray: [Function: isUint8ClampedArray], isUint16Array: [Function: isUint16Array], isUint32Array: [Function: isUint32Array], isInt8Array: [Function: isInt8Array], isInt16Array: [Function: isInt16Array], isInt32Array: [Function: isInt32Array], isFloat16Array: [Function: isFloat16Array], isFloat32Array: [Function: isFloat32Array], isFloat64Array: [Function: isFloat64Array], isBigInt64Array: [Function: isBigInt64Array], isBigUint64Array: [Function: isBigUint64Array], isKeyObject: [Function: value], isCryptoKey: [Function: value] }, parseEnv: [Function: parseEnv], parseArgs: [Function: parseArgs], TextDecoder: [class TextDecoder], TextEncoder: [class TextEncoder], MIMEType: [class MIMEType], MIMEParams: [class MIMEParams], diff: [Function: diff], setTraceSigInt: [Function: setTraceSigInt] }"
> util.inspect(util, { breakLength: Infinity, depth: Infinity })
'{\n' +
  '  _errnoException: [Function: _errnoException],\n' +
  '  _exceptionWithHostPort: [Function: _exceptionWithHostPort],\n' +
  '  _extend: [Function: deprecated],\n' +
  '  callbackify: [Function: callbackify],\n' +
  '  debug: [Function: debuglog],\n' +
  '  debuglog: [Function: debuglog],\n' +
  '  deprecate: [Function: deprecate],\n' +
  '  format: [Function: format],\n' +
  '  styleText: [Function: styleText],\n' +
  '  formatWithOptions: [Function: formatWithOptions],\n' +
  '  getCallSites: [Function: getCallSites],\n' +
  '  getSystemErrorMap: [Function: getSystemErrorMap],\n' +
  '  getSystemErrorName: [Function: getSystemErrorName],\n' +
  '  getSystemErrorMessage: [Function: getSystemErrorMessage],\n' +
  '  inherits: [Function: inherits],\n' +
  '  inspect: [Function: inspect] {\n' +
  '    custom: Symbol(nodejs.util.inspect.custom),\n' +
  '    colors: [Object: null prototype] { reset: [ 0, 0 ], bold: [ 1, 22 ], dim: [ 2, 22 ], italic: [ 3, 23 ], underline: [ 4, 24 ], blink: [ 5, 25 ], inverse: [ 7, 27 ], hidden: [ 8, 28 ], strikethrough: [ 9, 29 ], doubleunderline: [ 21, 24 ], black: [ 30, 39 ], red: [ 31, 39 ], green: [ 32, 39 ], yellow: [ 33, 39 ], blue: [ 34, 39 ], magenta: [ 35, 39 ], cyan: [ 36, 39 ], white: [ 37, 39 ], bgBlack: [ 40, 49 ], bgRed: [ 41, 49 ], bgGreen: [ 42, 49 ], bgYellow: [ 43, 49 ], bgBlue: [ 44, 49 ], bgMagenta: [ 45, 49 ], bgCyan: [ 46, 49 ], bgWhite: [ 47, 49 ], framed: [ 51, 54 ], overlined: [ 53, 55 ], gray: [ 90, 39 ], redBright: [ 91, 39 ], greenBright: [ 92, 39 ], yellowBright: [ 93, 39 ], blueBright: [ 94, 39 ], magentaBright: [ 95, 39 ], cyanBright: [ 96, 39 ], whiteBright: [ 97, 39 ], bgGray: [ 100, 49 ], bgRedBright: [ 101, 49 ], bgGreenBright: [ 102, 49 ], bgYellowBright: [ 103, 49 ], bgBlueBright: [ 104, 49 ], bgMagentaBright: [ 105, 49 ], bgCyanBright: [ 106, 49 ], bgWhiteBright: [ 107, 49 ] },\n' +
  "    styles: [Object: null prototype] { special: 'cyan', number: 'yellow', bigint: 'yellow', boolean: 'yellow', undefined: 'grey', null: 'bold', string: 'green', symbol: 'green', date: 'magenta', regexp: [Function: highlightRegExp] { colors: [ 'green', 'red', 'yellow', 'cyan', 'magenta' ] }, module: 'underline' },\n" +
  '    replDefaults: [Getter/Setter]\n' +
  '  },\n' +
  '  isArray: [Function: deprecated],\n' +
  '  isDeepStrictEqual: [Function: isDeepStrictEqual],\n' +
  '  promisify: [Function: promisify] { custom: Symbol(nodejs.util.promisify.custom) },\n' +
  '  stripVTControlCharacters: [Function: stripVTControlCharacters],\n' +
  '  toUSVString: [Function: toUSVString],\n' +
  '  transferableAbortSignal: [Getter],\n' +
  '  transferableAbortController: [Getter],\n' +
  '  aborted: [Getter],\n' +
  '  types: { isArgumentsObject: [Function (anonymous)], isArrayBuffer: [Function (anonymous)], isAsyncFunction: [Function (anonymous)], isBigIntObject: [Function (anonymous)], isBooleanObject: [Function (anonymous)], isDataView: [Function (anonymous)], isDate: [Function (anonymous)], isExternal: [Function (anonymous)], isGeneratorFunction: [Function (anonymous)], isGeneratorObject: [Function (anonymous)], isMap: [Function (anonymous)], isMapIterator: [Function (anonymous)], isModuleNamespaceObject: [Function (anonymous)], isNativeError: [Function (anonymous)], isNumberObject: [Function (anonymous)], isPromise: [Function (anonymous)], isProxy: [Function (anonymous)], isRegExp: [Function (anonymous)], isSet: [Function (anonymous)], isSetIterator: [Function (anonymous)], isSharedArrayBuffer: [Function (anonymous)], isStringObject: [Function (anonymous)], isSymbolObject: [Function (anonymous)], isWeakMap: [Function (anonymous)], isWeakSet: [Function (anonymous)], isAnyArrayBuffer: [Function (anonymous)], isBoxedPrimitive: [Function (anonymous)], isArrayBufferView: [Function: isView], isTypedArray: [Function: isTypedArray], isUint8Array: [Function: isUint8Array], isUint8ClampedArray: [Function: isUint8ClampedArray], isUint16Array: [Function: isUint16Array], isUint32Array: [Function: isUint32Array], isInt8Array: [Function: isInt8Array], isInt16Array: [Function: isInt16Array], isInt32Array: [Function: isInt32Array], isFloat16Array: [Function: isFloat16Array], isFloat32Array: [Function: isFloat32Array], isFloat64Array: [Function: isFloat64Array], isBigInt64Array: [Function: isBigInt64Array], isBigUint64Array: [Function: isBigUint64Array], isKeyObject: [Function: value], isCryptoKey: [Function: value] },\n' +
  '  parseEnv: [Function: parseEnv],\n' +
  '  parseArgs: [Function: parseArgs],\n' +
  '  TextDecoder: [class TextDecoder],\n' +
  '  TextEncoder: [class TextEncoder],\n' +
  '  MIMEType: [class MIMEType],\n' +
  '  MIMEParams: [class MIMEParams],\n' +
  '  diff: [Function: diff],\n' +
  '  setTraceSigInt: [Function: setTraceSigInt]\n' +
  '}'

How often does it reproduce? Is there a required condition?

Always reproducible when both breakLength and depth are set to Infinity.

What is the expected behavior? Why is that the expected behavior?

According to the Node.js documentation:

breakLength <integer>
The length at which input values are split across multiple lines.
Set to Infinity to format the input as a single line (in combination with compact set to true or any number >= 1).
Default: 80.

Therefore, when breakLength is set to Infinity, the output should always be rendered as a single line, regardless of object depth or size.

What do you see instead?

The output contains multiple lines with indentation, even though breakLength is set to Infinity.

This happens only when depth is also set to Infinity.

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs.utilIssues and PRs related to the built-in util module.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions