nodejs/node · error · TypeError
expected ${name}[${i}] to be a string or RegExp, got ${typeo
Error message
expected ${name}[${i}] to be a string or RegExp, got ${typeof origin} What it means
Thrown by assertCacheOrigins when the origins array contains an element that is neither a string nor a RegExp. Each entry must be an exact origin string (compared case-insensitively) or a RegExp tested against the lowercase origin. Numbers, objects, null, booleans, or URL objects are rejected.
Source
Thrown at deps/undici/src/lib/interceptor/cache.js:25
const MemoryCacheStore = require('../cache/memory-cache-store')
const CacheRevalidationHandler = require('../handler/cache-revalidation-handler')
const { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader, isInvalidOrWildcardVaryHeader } = require('../util/cache.js')
const { AbortError } = require('../core/errors.js')
const { parseHttpDate } = require('../util/date.js')
/**
* @param {(string | RegExp)[] | undefined} origins
* @param {string} name
*/
function assertCacheOrigins (origins, name) {
if (origins === undefined) return
if (!Array.isArray(origins)) {
throw new TypeError(`expected ${name} to be an array or undefined, got ${typeof origins}`)
}
for (let i = 0; i < origins.length; i++) {
const origin = origins[i]
if (typeof origin !== 'string' && !(origin instanceof RegExp)) {
throw new TypeError(`expected ${name}[${i}] to be a string or RegExp, got ${typeof origin}`)
}
}
}
const nop = () => {}
function trimOWS (value) {
return value.replace(/^[\t ]+|[\t ]+$/g, '')
}
function arrayIncludes (array, value) {
for (let i = 0; i < array.length; i++) {
if (array[i] === value) {
return true
}
}
return falseView on GitHub (pinned to 1b2de5e052)
Solutions
- Use plain origin strings or RegExps only; convert URL objects via url.origin.
- Filter the source list: origins.filter(o => typeof o === 'string' || o instanceof RegExp).
- Omit the origins option when the filtered list is empty.
Example fix
// before
client.compose(interceptors.cache({ origins: [new URL('https://api.example.com')] }))
// after
client.compose(interceptors.cache({
origins: ['https://api.example.com']
})) Defensive patterns
Strategy: type-guard
Validate before calling
function cleanOrigins(arr) {
return Array.isArray(arr) ? arr.filter(o => typeof o === 'string' || o instanceof RegExp) : undefined
} Type guard
function isOriginEntry(o) { return typeof o === 'string' || o instanceof RegExp } Try / catch
try { client.compose(interceptors.cache({ origins: arr })) } catch (e) { if (e instanceof TypeError && /string or RegExp/.test(e.message)) { client.compose(interceptors.cache({ origins: arr.filter(o => typeof o === 'string' || o instanceof RegExp) })) } else throw e } Prevention
- Use url.origin strings instead of URL objects.
- Filter mixed-type arrays before passing.
- Type origins as (string | RegExp)[] in TypeScript.
When it happens
Trigger: Passing origins: [new URL('https://a.com')] (URL object), ['https://a.com', 42], or origins: [null]; building the array from mixed-type config without filtering.
Common situations: Using URL objects instead of .toString()/.origin strings; optional entries pushed as null/undefined; JSON config with mixed types.
Related errors
- expected ${name} to be an array or undefined, got ${typeof o
- expected type of opts to be an Object, got ${opts === null ?
- expected opts.cacheByDefault to be number or undefined, got
- expected opts.type to be shared, private, or undefined, got
- expected type of opts to be an Object, got ${opts === null ?
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/575fd6799069a53a.
Report an issue: GitHub.