nodejs/node · error · InvalidArgumentError
${optionName} must be an array
Error message
${optionName} must be an array What it means
Thrown by normalizeStripHeaders when the stripHeadersOnRedirect or stripHeadersOnCrossOriginRedirect option is present but is not an array. These options let you list extra header names to drop when following a redirect (same-origin) or when the redirect crosses origins. Both must be arrays of header-name strings (or null/undefined to leave them unset).
Source
Thrown at deps/undici/src/lib/handler/redirect-handler.js:185
return true
}
if (removeContent && name.startsWith('content-')) {
return true
}
if (unknownOrigin) {
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
}
return false
}
// https://tools.ietf.org/html/rfc7231#section-6.4
function normalizeStripHeaders (headers, optionName) {
if (headers == null) {
return null
}
if (!Array.isArray(headers)) {
throw new InvalidArgumentError(`${optionName} must be an array`)
}
const normalized = new Set()
for (const header of headers) {
if (typeof header !== 'string') {
throw new InvalidArgumentError(`${optionName} must contain header names`)
}
normalized.add(util.headerNameToString(header))
}
return normalized
}
function cleanRequestHeaders (headers, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) {
const ret = []
if (Array.isArray(headers)) {
for (let i = 0; i < headers.length; i += 2) {
if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) {View on GitHub (pinned to 1b2de5e052)
Solutions
- Pass header names as an array of strings: ['authorization', 'x-api-key'].
- If you have a Set or comma-separated string, convert first: Array.from(set) or str.split(',').
- Omit the option when you only want the default Host/Content-* stripping behavior.
Example fix
// before
new Agent({ maxRedirections: 5, stripHeadersOnRedirect: 'authorization,cookie' })
// after
new Agent({ maxRedirections: 5, stripHeadersOnRedirect: ['authorization', 'cookie'] }) Defensive patterns
Strategy: validation
Validate before calling
function normalizeStripHeaders(v) {
if (v == null) return undefined
if (!Array.isArray(v)) return [String(v)]
return v.filter(h => typeof h === 'string')
} Type guard
function isStripHeaders(v) { return v == null || (Array.isArray(v) && v.every(h => typeof h === 'string')) } Try / catch
try { new Agent({ maxRedirections: 5, stripHeadersOnRedirect: list }) } catch (e) { if (e.code === 'UND_ERR_INVALID_ARG') { new Agent({ maxRedirections: 5, stripHeadersOnRedirect: Array.isArray(list) ? list : [list].filter(String) }) } else throw e } Prevention
- Always pass header lists as arrays of strings.
- Convert Sets/comma-strings at the config boundary.
- Omit the option to keep default Host/Content-* stripping.
When it happens
Trigger: Passing stripHeadersOnRedirect / stripHeadersOnCrossOriginRedirect as a string (e.g. 'authorization'), a Set, an object, or a comma-separated list instead of an array, in Agent/Pool/Client opts or per-request opts.
Common situations: Migrating from a config format that used a single string or a Set; copying header-list config from another library that accepts different shapes; TypeScript where the type was loosened.
Related errors
- ${optionName} must contain header names
- maxRedirections must be a positive number
- throwOnMaxRedirect must be a boolean
- 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/97e8a7e8dcc3cab4.
Report an issue: GitHub.