{"record":{"id":"38bc98e156498dbf","repo":"nodejs/node","slug":"expected-opts-cachebydefault-to-be-number-or-undef","errorCode":null,"errorMessage":"expected opts.cacheByDefault to be number or undefined, got ${typeof cacheByDefault}","messagePattern":"expected opts\\.cacheByDefault to be number or undefined, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/interceptor/cache.js","lineNumber":519,"sourceCode":"module.exports = (opts = {}) => {\n  const {\n    store = new MemoryCacheStore(),\n    methods = ['GET'],\n    cacheByDefault = undefined,\n    type = 'shared',\n    origins = undefined\n  } = opts\n\n  if (typeof opts !== 'object' || opts === null) {\n    throw new TypeError(`expected type of opts to be an Object, got ${opts === null ? 'null' : typeof opts}`)\n  }\n\n  assertCacheStore(store, 'opts.store')\n  assertCacheMethods(methods, 'opts.methods')\n  assertCacheOrigins(origins, 'opts.origins')\n\n  if (typeof cacheByDefault !== 'undefined' && typeof cacheByDefault !== 'number') {\n    throw new TypeError(`expected opts.cacheByDefault to be number or undefined, got ${typeof cacheByDefault}`)\n  }\n\n  if (typeof type !== 'undefined' && type !== 'shared' && type !== 'private') {\n    throw new TypeError(`expected opts.type to be shared, private, or undefined, got ${typeof type}`)\n  }\n\n  const globalOpts = {\n    store,\n    methods,\n    cacheByDefault,\n    type\n  }\n\n  const safeMethodsToNotCache = []\n  for (let i = 0; i < util.safeHTTPMethods.length; i++) {\n    const method = util.safeHTTPMethods[i]\n    if (!arrayIncludes(methods, method)) {\n      safeMethodsToNotCache.push(method)","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/interceptor/cache.js#L501-L537","documentation":"Thrown by the cache() interceptor factory when opts.cacheByDefault is present but not a number. cacheByDefault, when set, instructs the interceptor to cache responses even without explicit Cache-Control (treating them as fresh for the given number of seconds). It must be a number (seconds) or undefined; strings, booleans, etc. are rejected.","triggerScenarios":"Passing cacheByDefault as a string ('60'), a boolean (true), or any non-number in cache() interceptor opts.","commonSituations":"Reading the TTL from config/env as a string; assuming true means 'enable'; mixing units (minutes vs seconds).","solutions":["Pass a numeric seconds value: cacheByDefault: 60.","Coerce strings: Number(value) and confirm Number.isFinite before passing.","Omit the option if you only want to cache responses that carry explicit Cache-Control headers."],"exampleFix":"// before\nclient.compose(interceptors.cache({ cacheByDefault: '60' }))\n\n// after\nclient.compose(interceptors.cache({ cacheByDefault: 60 }))","handlingStrategy":"type-guard","validationCode":"function resolveCacheByDefault(v) {\n  if (v == null) return undefined\n  const n = Number(v)\n  return Number.isFinite(n) ? n : undefined\n}","typeGuard":"function isCacheByDefault(v) { return v == null || typeof v === 'number' }","tryCatchPattern":"try { client.compose(interceptors.cache({ cacheByDefault })) } catch (e) { if (e instanceof TypeError && /cacheByDefault/.test(e.message)) { client.compose(interceptors.cache({ cacheByDefault: Number(cacheByDefault) || undefined })) } else throw e }","preventionTips":["Pass cacheByDefault as a number of seconds.","Coerce env/config strings with Number() + isFinite.","Omit when you only want explicit Cache-Control caching."],"tags":["undici","http","cache","interceptor","configuration","validation","ttl"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}