nodejs/node · error · TypeError

expected opts.maxBufferSize to be a positive finite number,

Error message

expected opts.maxBufferSize to be a positive finite number, got ${maxBufferSize}

What it means

Thrown by the deduplicate interceptor when `maxBufferSize` (default `5 * 1024 * 1024` bytes) is not a positive finite number. The deduplicate handler buffers the leading bytes of a response so it can replay them to wait-listed callers before streaming; once the buffer exceeds `maxBufferSize` it stops accepting new waiters and sends extra requests independently. An invalid cap would either never allow coalescing (zero/negative) or permit unbounded memory growth (`Infinity`), so the factory rejects both.

Source

Thrown at deps/undici/src/lib/interceptor/deduplicate.js:45

    throw new TypeError(`expected opts.methods to be an array, got ${typeof methods}`)
  }

  for (const method of methods) {
    if (!util.safeHTTPMethods.includes(method)) {
      throw new TypeError(`expected opts.methods to only contain safe HTTP methods, got ${method}`)
    }
  }

  if (!Array.isArray(skipHeaderNames)) {
    throw new TypeError(`expected opts.skipHeaderNames to be an array, got ${typeof skipHeaderNames}`)
  }

  if (!Array.isArray(excludeHeaderNames)) {
    throw new TypeError(`expected opts.excludeHeaderNames to be an array, got ${typeof excludeHeaderNames}`)
  }

  if (!Number.isFinite(maxBufferSize) || maxBufferSize <= 0) {
    throw new TypeError(`expected opts.maxBufferSize to be a positive finite number, got ${maxBufferSize}`)
  }

  // Convert to lowercase Set for case-insensitive header matching
  const skipHeaderNamesSet = new Set(skipHeaderNames.map(name => name.toLowerCase()))

  // Convert to lowercase Set for case-insensitive header exclusion from deduplication key
  const excludeHeaderNamesSet = new Set(excludeHeaderNames.map(name => name.toLowerCase()))

  /**
   * Map of pending requests for deduplication
   * @type {Map<string, DeduplicationHandler>}
   */
  const pendingRequests = new Map()

  return dispatch => {
    return (opts, handler) => {
      if (opts.upgrade || methods.includes(opts.method) === false) {
        return dispatch(opts, handler)

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Pass a positive finite integer byte count, e.g. `maxBufferSize: 10 * 1024 * 1024` for 10 MiB.
  2. If loading from config/env, coerce and parse: `Number(process.env.DEDUP_BUFFER ?? 5_242_880)` and validate `Number.isFinite(v) && v > 0`.
  3. Do not pass `0` to 'disable' buffering — omit the option to keep the 5 MiB default, or raise it if responses are large.

Example fix

// before
deduplicate({ maxBufferSize: process.env.DEDUP_BUFFER }) // env is a string '5242880'
deduplicate({ maxBufferSize: 0 })

// after
deduplicate({ maxBufferSize: Number(process.env.DEDUP_BUFFER) })
deduplicate({ maxBufferSize: 10 * 1024 * 1024 })
Defensive patterns

Strategy: validation

Validate before calling

function validateMaxBufferSize(v) {
  const n = Number(v)
  if (!Number.isFinite(n) || n <= 0) {
    throw new TypeError('maxBufferSize must be a positive finite number')
  }
  return n
}

Type guard

function isPositiveFinite(v) {
  return typeof v === 'number' && Number.isFinite(v) && v > 0
}

Prevention

When it happens

Trigger: Passing `maxBufferSize: 0`, a negative number, `NaN`, `Infinity`, or a non-number (string `'5mb'`). `Number.isFinite` rules out NaN and ±Infinity, and `maxBufferSize <= 0` rules out zero and negatives. Default is 5 MiB.

Common situations: Reading a size from env/config as a string (e.g. `process.env.DEDUP_BUFFER` without `Number()`); using a human-readable size like `'5mb'` without parsing; setting 0 thinking it disables buffering (it does not — it errors).

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/e0c26b6da57cc1c0. Report an issue: GitHub.