How to fix RangeError: util.inspect depth must be a non-negative integer in Node.js

Node.jsBEGINNERLOWUpdated Dec 9, 2025· 91 views

This error occurs when you pass an invalid depth value to Node.js util.inspect() function. The depth parameter must be a non-negative integer (0 or greater), null, or Infinity—passing a negative number triggers this RangeError.

Quick fix

Fixes RangeError: util.inspect depth must be a non-negative integer

RangeError: util.inspect depth must be a non-negative integer
    at formatValue (node:internal/util/inspect:482:11)
    at inspect (node:internal/util/inspect:254:10)
    at /path/to/your/file.js:25:18
  1. Locate the util.inspect call causing the error
  2. Check the depth value before calling util.inspect
  3. Ensure depth is a non-negative integer
  4. Fix dynamic depth calculations
node.js — error
RangeError: util.inspect depth must be a non-negative integer
at formatValue (node:internal/util/inspect:482:11)
at inspect (node:internal/util/inspect:254:10)
at /path/to/your/file.js:25:18
RangeError: util.inspect depth must be a non-negative integer

What this error means

The RangeError for util.inspect depth occurs when the depth option is set to a negative number. The depth parameter controls how many levels deep Node.js will recurse when inspecting an object for debugging or logging purposes. Node.js util.inspect() is commonly used to convert objects to human-readable strings, and the depth option limits recursion to prevent overwhelming output on deeply nested structures. Valid values are non-negative integers (0, 1, 2, etc.), null (infinite depth), or Infinity. When a negative value is passed—whether directly or through a variable—Node.js immediately throws this RangeError to prevent invalid behavior. This error typically happens when depth values are computed dynamically, come from configuration files without validation, or result from mathematical operations that produce negative results. It's a runtime validation error that ensures the depth parameter stays within sensible bounds.

Typical symptoms

  • Node.js process crashes with RangeError during object inspection or logging
  • Error appears when using console.log, console.dir, or util.inspect with objects
  • Stack trace points to util.inspect or custom inspection functions
  • Debugging or logging code fails unexpectedly
  • Error message specifically mentions 'depth must be a non-negative integer'
  • Issue appears when using depth option in logging libraries

Common causes

  1. Passing a negative number directly to the depth option in util.inspect
  2. Dynamic calculation of depth that produces negative values
  3. Configuration file or environment variable contains negative depth value
  4. Incorrect default value assignment for depth parameter
  5. Mathematical operations (subtraction, decrements) that go below zero
  6. Using relative depth adjustments without bounds checking
  7. Passing depth through function parameters without validation
  8. Type coercion issues converting non-numeric values to negative numbers

How to fix "RangeError: util.inspect depth must be a non-negative integer"

1Locate the util.inspect call causing the error

Check the stack trace to identify where util.inspect is being called with an invalid depth:

bash
RangeError: util.inspect depth must be a non-negative integer
    at formatValue (node:internal/util/inspect:482:11)
    at inspect (node:internal/util/inspect:254:10)
    at /path/to/your/file.js:25:18

Look at line 25 in your file to see how the depth option is being set.

2Check the depth value before calling util.inspect

Add console.log or use a debugger to verify what depth value is being passed:

javascript
const util = require('util');

const myObject = { a: { b: { c: 'deep' } } };
const depth = getDepthFromConfig(); // Could be negative

console.log('depth value:', depth);
console.log('depth type:', typeof depth);

// This might fail if depth is negative
console.log(util.inspect(myObject, { depth }));

Use console.log to inspect the actual depth value before it's used.

3Ensure depth is a non-negative integer

Validate the depth parameter before passing it to util.inspect:

javascript
const util = require('util');

// ❌ BAD - depth might be negative
let depth = config.inspectDepth;
console.log(util.inspect(obj, { depth }));

// ✓ GOOD - Validate depth is non-negative
let depth = config.inspectDepth;
if (typeof depth === 'number' && depth < 0) {
  console.warn('Invalid depth value, using default of 2');
  depth = 2;
}
console.log(util.inspect(obj, { depth }));

// ✓ GOOD - Use Math.max to ensure non-negative
let depth = Math.max(0, config.inspectDepth);
console.log(util.inspect(obj, { depth }));

// ✓ GOOD - Use default with fallback
let depth = config.inspectDepth ?? 2;
if (typeof depth !== 'number' || depth < 0) {
  depth = 2;
}
console.log(util.inspect(obj, { depth }));

Always check that depth is a non-negative number before use.

4Fix dynamic depth calculations

If you're calculating depth dynamically, add bounds checking:

javascript
const util = require('util');

// ❌ BAD - Subtraction can go negative
const maxDepth = 3;
const currentLevel = 5;
const depth = maxDepth - currentLevel; // Results in -2
console.log(util.inspect(obj, { depth }));

// ✓ GOOD - Use Math.max to prevent negative values
const maxDepth = 3;
const currentLevel = 5;
const depth = Math.max(0, maxDepth - currentLevel); // Results in 0
console.log(util.inspect(obj, { depth }));

// ✓ GOOD - Check before use
let depth = maxDepth - currentLevel;
if (depth < 0) {
  console.warn('Depth calculation resulted in negative value, using 0');
  depth = 0;
}
console.log(util.inspect(obj, { depth }));

Use Math.max(0, ...) to ensure calculations never go negative.

5Validate depth from configuration sources

When loading depth from config files or environment variables, validate the value:

javascript
const util = require('util');

// ❌ BAD - No validation
const depth = parseInt(process.env.INSPECT_DEPTH);
console.log(util.inspect(obj, { depth }));

// ✓ GOOD - Validate and provide safe default
function getValidDepth(value, defaultDepth = 2) {
  const parsed = parseInt(value, 10);
  if (isNaN(parsed) || parsed < 0) {
    console.warn(`Invalid depth value: ${value}, using default: ${defaultDepth}`);
    return defaultDepth;
  }
  return parsed;
}

const depth = getValidDepth(process.env.INSPECT_DEPTH);
console.log(util.inspect(obj, { depth }));

// ✓ GOOD - Use schema validation with Zod
import { z } from 'zod';

const ConfigSchema = z.object({
  inspectDepth: z.number().int().nonnegative().default(2),
});

const config = ConfigSchema.parse({
  inspectDepth: process.env.INSPECT_DEPTH,
});
console.log(util.inspect(obj, { depth: config.inspectDepth }));

Always validate external configuration values before using them.

6Use special depth values correctly

Node.js accepts null or Infinity for unlimited depth:

javascript
const util = require('util');

// ✓ Non-negative integer
console.log(util.inspect(obj, { depth: 0 })); // Shallow
console.log(util.inspect(obj, { depth: 2 })); // Default
console.log(util.inspect(obj, { depth: 10 })); // Deep

// ✓ Infinite depth (use with caution on circular objects)
console.log(util.inspect(obj, { depth: null }));
console.log(util.inspect(obj, { depth: Infinity }));

// ❌ Invalid values
console.log(util.inspect(obj, { depth: -1 })); // RangeError
console.log(util.inspect(obj, { depth: -5 })); // RangeError
console.log(util.inspect(obj, { depth: 1.5 })); // Works but should be integer

Use null or Infinity for unlimited inspection, but be careful with circular references.

Advanced notes

Understanding util.inspect Depth Parameter

The depth parameter in util.inspect determines how many levels of nested properties Node.js will show before replacing deeper objects with [Object] or [Array]. This is crucial for performance and readability:

javascript
const util = require('util');

const deepObject = {
  level1: {
    level2: {
      level3: {
        level4: 'deep value'
      }
    }
  }
};

// Depth 0: Only top level
console.log(util.inspect(deepObject, { depth: 0 }));
// Output: { level1: [Object] }

// Depth 1: One level deep
console.log(util.inspect(deepObject, { depth: 1 }));
// Output: { level1: { level2: [Object] } }

// Depth 2: Two levels deep (default)
console.log(util.inspect(deepObject, { depth: 2 }));
// Output: { level1: { level2: { level3: [Object] } } }

// Depth null: Infinite (shows everything)
console.log(util.inspect(deepObject, { depth: null }));
// Output: { level1: { level2: { level3: { level4: 'deep value' } } } }

Performance Considerations

Setting depth to null or Infinity on large objects can cause:
- Excessive memory usage
- Slow string conversion
- Console flooding
- Stack overflow on circular references

Always use appropriate depth limits for production logging.

Custom Inspection Functions

When implementing custom [util.inspect.custom] methods, properly handle depth:

javascript
const util = require('util');

class MyClass {
  constructor() {
    this.nested = { data: { deep: 'value' } };
  }

  [util.inspect.custom](depth, options) {
    // Check if depth limit reached
    if (depth < 0) {
      return options.stylize('[MyClass]', 'special');
    }

    // Decrease depth for nested inspection
    const newOptions = Object.assign({}, options, {
      depth: options.depth === null ? null : options.depth - 1
    });

    return `MyClass ${util.inspect(this.nested, newOptions)}`;
  }
}

const instance = new MyClass();
console.log(util.inspect(instance, { depth: 1 }));

This pattern ensures your custom inspection respects depth limits.

Console.dir and Depth

The console.dir() method uses util.inspect internally and also accepts depth:

javascript
const obj = { a: { b: { c: 'd' } } };

// These are equivalent
console.dir(obj, { depth: 3 });
console.log(util.inspect(obj, { depth: 3 }));

// Default depth for console.dir is 2
console.dir(obj); // Same as { depth: 2 }

Depth in Logging Libraries

Popular logging libraries (Winston, Bunyan, Pino) often use util.inspect internally:

javascript
// Winston example
const winston = require('winston');

const logger = winston.createLogger({
  format: winston.format.printf(info => {
    // Ensure depth is valid when inspecting
    const depth = process.env.LOG_DEPTH ? Math.max(0, parseInt(process.env.LOG_DEPTH, 10)) : 3;
    return util.inspect(info, { depth, colors: true });
  }),
  transports: [new winston.transports.Console()]
});

Always validate depth configuration in logging setup.

Debugging Depth Issues

Create a helper function to safely inspect with configurable depth:

javascript
const util = require('util');

function safeInspect(obj, options = {}) {
  const defaults = {
    depth: 2,
    colors: true,
    maxArrayLength: 100,
    breakLength: 80,
    compact: false
  };

  // Merge options and validate depth
  const mergedOptions = { ...defaults, ...options };

  if (typeof mergedOptions.depth === 'number' && mergedOptions.depth < 0) {
    console.warn('Negative depth provided, using 0');
    mergedOptions.depth = 0;
  }

  return util.inspect(obj, mergedOptions);
}

// Safe to use with any depth value
console.log(safeInspect(obj, { depth: -5 })); // Warns and uses 0
console.log(safeInspect(obj, { depth: 10 })); // Works fine
console.log(safeInspect(obj, { depth: null })); // Infinite depth

This wrapper prevents RangeError and provides sensible defaults.

TypeScript Type Safety

Define proper types for inspect options:

typescript
import util from 'util';

interface SafeInspectOptions {
  depth?: number | null; // Non-negative or null
  colors?: boolean;
  compact?: boolean;
}

function safeInspect(obj: unknown, options: SafeInspectOptions = {}): string {
  const depth = options.depth ?? 2;

  // Type guard ensures depth is valid
  if (typeof depth === 'number' && depth < 0) {
    throw new Error('Depth must be non-negative');
  }

  return util.inspect(obj, { ...options, depth });
}

TypeScript helps catch invalid depth values at compile time.

Frequently asked questions

What does "RangeError: util.inspect depth must be a non-negative integer" mean?
inspect depth occurs when the depth option is set to a negative number. js will recurse when inspecting an object for debugging or logging purposes. inspect() is commonly used to convert objects to human-readable strings, and the depth option limits recursion to prevent overwhelming output on deeply nested structures.
How do I fix "RangeError: util.inspect depth must be a non-negative integer"?
This error occurs when you pass an invalid depth value to Node.js util.inspect() function. The depth parameter must be a non-negative integer (0 or greater), null, or Infinity—passing a negative number triggers this RangeError.
What causes "RangeError: util.inspect depth must be a non-negative integer"?
Passing a negative number directly to the depth option in util.inspect Dynamic calculation of depth that produces negative values Configuration file or environment variable contains negative depth value
Is the "RangeError: util.inspect depth must be a non-negative integer" error serious?
It is a low-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading