nodejs/node · error · InvalidArgumentError
maxRedirections must be a positive number
Error message
maxRedirections must be a positive number
What it means
Thrown by undici's RedirectHandler.buildDispatch when wiring up the redirect-dispatch wrapper. The maxRedirections option (set via new Agent({ maxRedirections }), the redirect() interceptor, or per-request opts) must be null/undefined or a non-negative integer. Note the message says 'positive' but 0 is actually accepted (it disables following redirects); floats, negatives, strings, Infinity, and NaN are rejected.
Source
Thrown at deps/undici/src/lib/handler/redirect-handler.js:14
'use strict'
const util = require('../core/util')
const assert = require('node:assert')
const { InvalidArgumentError } = require('../core/errors')
const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]
const noop = () => {}
class RedirectHandler {
static buildDispatch (dispatcher, maxRedirections) {
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}
const dispatch = dispatcher.dispatch.bind(dispatcher)
return (opts, originalHandler) => dispatch(opts, new RedirectHandler(dispatch, maxRedirections, opts, originalHandler))
}
constructor (dispatch, maxRedirections, opts, handler) {
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}
if (opts.throwOnMaxRedirect != null && typeof opts.throwOnMaxRedirect !== 'boolean') {
throw new InvalidArgumentError('throwOnMaxRedirect must be a boolean')
}
this.dispatch = dispatch
this.location = null
const { maxRedirections: _, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect, ...cleanOpts } = optsView on GitHub (pinned to 1b2de5e052)
Solutions
- Coerce the value to a non-negative integer before passing it: Math.max(0, Math.trunc(Number(value))).
- Pass null or undefined (or simply omit the option) if you do not want redirects followed.
- Validate env-sourced values explicitly and fall back to a sensible default when parsing fails.
Example fix
// before
const agent = new Agent({ maxRedirections: process.env.MAX_REDIRECTS })
// after
const raw = Number.parseInt(process.env.MAX_REDIRECTS ?? '', 10)
const agent = new Agent({
maxRedirections: Number.isFinite(raw) ? Math.max(0, raw) : undefined
}) Defensive patterns
Strategy: validation
Validate before calling
function resolveMaxRedirections(value) {
if (value == null) return undefined
const n = Math.trunc(Number(value))
if (!Number.isFinite(n) || n < 0) {
throw new Error(`maxRedirections must be a non-negative integer, got ${String(value)}`)
}
return n
}
// usage: new Agent({ maxRedirections: resolveMaxRedirections(process.env.MAX_REDIRECTS) }) Type guard
function isMaxRedirections(v) {
return v == null || (Number.isInteger(v) && v >= 0)
} Try / catch
try { const agent = new Agent({ maxRedirections }) } catch (e) { if (e.code === 'UND_ERR_INVALID_ARG') { /* reconfigure with a sane default */ } else throw e } Prevention
- Never forward env/config strings directly; always Number() + isFinite guard.
- Keep one normalization helper for maxRedirections and reuse it everywhere.
- Omit the option when you do not need redirect following.
When it happens
Trigger: Passing maxRedirections as a string (e.g. read straight from an env var), a float like 1.5, a negative number, or NaN when constructing an Agent/Pool/Client with redirects enabled, or when composing the redirect() interceptor.
Common situations: Reading maxRedirections from process.env or a YAML/JSON config without coercing to a Number; TypeScript code where a string|number union slips through; passing parseInt() result that yielded NaN on bad input.
Related errors
- throwOnMaxRedirect must be a boolean
- ${optionName} must be an array
- ${optionName} must contain header names
- expected ${name} to be an array or undefined, got ${typeof o
- expected ${name}[${i}] to be a string or RegExp, got ${typeo
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/55e2ae5fa653215f.
Report an issue: GitHub.