{"record":{"id":"575fd6799069a53a","repo":"nodejs/node","slug":"expected-name-i-to-be-a-string-or-regexp-g","errorCode":null,"errorMessage":"expected ${name}[${i}] to be a string or RegExp, got ${typeof origin}","messagePattern":"expected (.+?)\\[(.+?)\\] to be a string or RegExp, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/interceptor/cache.js","lineNumber":25,"sourceCode":"const MemoryCacheStore = require('../cache/memory-cache-store')\nconst CacheRevalidationHandler = require('../handler/cache-revalidation-handler')\nconst { assertCacheStore, assertCacheMethods, makeCacheKey, normalizeHeaders, parseCacheControlHeader, isInvalidOrWildcardVaryHeader } = require('../util/cache.js')\nconst { AbortError } = require('../core/errors.js')\nconst { parseHttpDate } = require('../util/date.js')\n\n/**\n * @param {(string | RegExp)[] | undefined} origins\n * @param {string} name\n */\nfunction assertCacheOrigins (origins, name) {\n  if (origins === undefined) return\n  if (!Array.isArray(origins)) {\n    throw new TypeError(`expected ${name} to be an array or undefined, got ${typeof origins}`)\n  }\n  for (let i = 0; i < origins.length; i++) {\n    const origin = origins[i]\n    if (typeof origin !== 'string' && !(origin instanceof RegExp)) {\n      throw new TypeError(`expected ${name}[${i}] to be a string or RegExp, got ${typeof origin}`)\n    }\n  }\n}\n\nconst nop = () => {}\n\nfunction trimOWS (value) {\n  return value.replace(/^[\\t ]+|[\\t ]+$/g, '')\n}\n\nfunction arrayIncludes (array, value) {\n  for (let i = 0; i < array.length; i++) {\n    if (array[i] === value) {\n      return true\n    }\n  }\n\n  return false","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/interceptor/cache.js#L7-L43","documentation":"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.","triggerScenarios":"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.","commonSituations":"Using URL objects instead of .toString()/.origin strings; optional entries pushed as null/undefined; JSON config with mixed types.","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."],"exampleFix":"// before\nclient.compose(interceptors.cache({ origins: [new URL('https://api.example.com')] }))\n\n// after\nclient.compose(interceptors.cache({\n  origins: ['https://api.example.com']\n}))","handlingStrategy":"type-guard","validationCode":"function cleanOrigins(arr) {\n  return Array.isArray(arr) ? arr.filter(o => typeof o === 'string' || o instanceof RegExp) : undefined\n}","typeGuard":"function isOriginEntry(o) { return typeof o === 'string' || o instanceof RegExp }","tryCatchPattern":"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 }","preventionTips":["Use url.origin strings instead of URL objects.","Filter mixed-type arrays before passing.","Type origins as (string | RegExp)[] in TypeScript."],"tags":["undici","http","cache","interceptor","configuration","validation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}