{"record":{"id":"04d3ed8b280ac428","repo":"nodejs/node","slug":"expected-type-of-opts-to-be-an-object-got-opts-04d3ed","errorCode":null,"errorMessage":"expected type of opts to be an Object, got ${opts === null ? 'null' : typeof opts}","messagePattern":"expected type of opts to be an Object, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/interceptor/deduplicate.js","lineNumber":23,"sourceCode":"const DeduplicationHandler = require('../handler/deduplication-handler')\nconst { normalizeHeaders, makeCacheKey, makeDeduplicationKey } = require('../util/cache.js')\n\nconst pendingRequestsChannel = diagnosticsChannel.channel('undici:request:pending-requests')\n\n/**\n * @param {import('../../types/interceptors.d.ts').default.DeduplicateInterceptorOpts} [opts]\n * @returns {import('../../types/dispatcher.d.ts').default.DispatcherComposeInterceptor}\n */\nmodule.exports = (opts = {}) => {\n  const {\n    methods = ['GET'],\n    skipHeaderNames = [],\n    excludeHeaderNames = [],\n    maxBufferSize = 5 * 1024 * 1024\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  if (!Array.isArray(methods)) {\n    throw new TypeError(`expected opts.methods to be an array, got ${typeof methods}`)\n  }\n\n  for (const method of methods) {\n    if (!util.safeHTTPMethods.includes(method)) {\n      throw new TypeError(`expected opts.methods to only contain safe HTTP methods, got ${method}`)\n    }\n  }\n\n  if (!Array.isArray(skipHeaderNames)) {\n    throw new TypeError(`expected opts.skipHeaderNames to be an array, got ${typeof skipHeaderNames}`)\n  }\n\n  if (!Array.isArray(excludeHeaderNames)) {\n    throw new TypeError(`expected opts.excludeHeaderNames to be an array, got ${typeof excludeHeaderNames}`)","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/interceptor/deduplicate.js#L5-L41","documentation":"Thrown by the deduplicate() interceptor factory when the opts argument is not an object. The factory signature is (opts = {}), so opts must be an object or undefined (to use defaults); null, strings, numbers, arrays, and booleans are rejected. null is reported as 'null' rather than 'object'.","triggerScenarios":"Calling interceptors.deduplicate(null), interceptors.deduplicate(false), interceptors.deduplicate('GET'), or forwarding a primitive as the opts argument.","commonSituations":"Conditionally passing config and accidentally forwarding null/undefined-as-null; spreading a config that resolved to a falsy primitive; misreading the API as accepting a method string.","solutions":["Pass an object or omit the argument entirely: interceptors.deduplicate() uses defaults.","Normalize dynamic config: const opts = config ?? undefined before composing.","Guard with typeof opts === 'object' && opts !== null before forwarding."],"exampleFix":"// before\nclient.compose(interceptors.deduplicate(maybeConfig)) // maybeConfig can be null\n\n// after\nclient.compose(interceptors.deduplicate(maybeConfig ?? undefined))\n// or simply\nclient.compose(interceptors.deduplicate())","handlingStrategy":"type-guard","validationCode":"const dedupOpts = (typeof cfg === 'object' && cfg !== null) ? cfg : undefined\nclient.compose(interceptors.deduplicate(dedupOpts))","typeGuard":"function isDedupOpts(v) { return v == null || (typeof v === 'object' && !Array.isArray(v)) }","tryCatchPattern":"try { client.compose(interceptors.deduplicate(opts)) } catch (e) { if (e instanceof TypeError && /opts to be an Object/.test(e.message)) { client.compose(interceptors.deduplicate()) } else throw e }","preventionTips":["Omit the argument to use defaults.","Normalize config with ?? undefined before forwarding.","Guard typeof at the boundary."],"tags":["undici","http","deduplicate","interceptor","configuration","validation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}