{"record":{"id":"efe484bd26e22e50","repo":"nodejs/node","slug":"und-err-invalid-arg-efe484","errorCode":"UND_ERR_INVALID_ARG","errorMessage":"Invalid lookup. Must be a function","messagePattern":"Invalid lookup\\. Must be a function","errorType":"validation","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/interceptor/dns.js","lineNumber":495,"sourceCode":"    interceptorOpts?.affinity != null &&\n    interceptorOpts?.affinity !== 4 &&\n    interceptorOpts?.affinity !== 6\n  ) {\n    throw new InvalidArgumentError('Invalid affinity. Must be either 4 or 6')\n  }\n\n  if (\n    interceptorOpts?.dualStack != null &&\n    typeof interceptorOpts?.dualStack !== 'boolean'\n  ) {\n    throw new InvalidArgumentError('Invalid dualStack. Must be a boolean')\n  }\n\n  if (\n    interceptorOpts?.lookup != null &&\n    typeof interceptorOpts?.lookup !== 'function'\n  ) {\n    throw new InvalidArgumentError('Invalid lookup. Must be a function')\n  }\n\n  if (\n    interceptorOpts?.pick != null &&\n    typeof interceptorOpts?.pick !== 'function'\n  ) {\n    throw new InvalidArgumentError('Invalid pick. Must be a function')\n  }\n\n  if (\n    interceptorOpts?.storage != null &&\n    (typeof interceptorOpts?.storage?.get !== 'function' ||\n      typeof interceptorOpts?.storage?.set !== 'function' ||\n      typeof interceptorOpts?.storage?.full !== 'function' ||\n      typeof interceptorOpts?.storage?.delete !== 'function'\n    )\n  ) {\n    throw new InvalidArgumentError('Invalid storage. Must be a object with methods: { get, set, full, delete }')","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/interceptor/dns.js#L477-L513","documentation":"Thrown by the DNS interceptor factory (`InvalidArgumentError`, code `UND_ERR_INVALID_ARG`) when `lookup` is provided and is not a function. `lookup` lets you plug in a custom resolver (e.g. `dns.lookup`, a multi-resolver strategy, or a service-discovery hook) instead of the default Node resolver. The interceptor calls it per hostname to obtain address records, so anything non-callable would fail at runtime inside the dispatch path.","triggerScenarios":"Passing `lookup: 'dns.lookup'` (a string name), an object `{ resolve: fn }`, a hostname string, or a value that is not callable. The guard is `lookup != null && typeof !== 'function'`.","commonSituations":"Referencing `dns.lookup` without importing `node:dns`; passing a bound method's name as a string; wrapping the resolver in an object (e.g. `{ lookup: realLookup }`) and passing the wrapper instead of the function. Default behavior uses Node's built-in resolver, so omit unless you need customization.","solutions":["Pass a function reference, e.g. `lookup: dns.lookup` after `const dns = require('node:dns')`, or `lookup: myCustomResolver`.","Make sure you import the function, not the module: pass `dns.lookup`, not `dns`.","If using a service-discovery client, pass its resolve callback directly, not a config object wrapping it."],"exampleFix":"// before\nconst dns = require('node:dns')\ninterceptor dns({ lookup: 'dns.lookup' })\ndns({ lookup: { resolve: customResolve } })\n\n// after\ndns({ lookup: dns.lookup })\ndns({ lookup: customResolve })","handlingStrategy":"type-guard","validationCode":"function validateLookup(v) {\n  if (v == null) return undefined\n  if (typeof v !== 'function') throw new Error('lookup must be a function')\n  return v\n}","typeGuard":"function isFunction(v) {\n  return typeof v === 'function'\n}","tryCatchPattern":null,"preventionTips":["Pass the resolver function reference, not a string or module.","Import node:dns and pass dns.lookup directly."],"tags":["undici","interceptor","dns","resolver","validation","config"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}