denoland/deno · error · TypeError
ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
Error message
The "options" argument must be of type object or integer. Received ${options} What it means
dns.promises.lookup() accepts options as either an integer IP family or an options object (hints, family, all, order, ...). The polyfill tests options with isFamily() (integer, then validated against validFamilies) and isLookupOptions() (options-object shape); anything else - strings, booleans, arrays, null - throws ERR_INVALID_ARG_TYPE listing ['integer', 'object'].
Source
Thrown at ext/node/polyfills/internal/dns/promises.ts:192
function lookup(
hostname: string,
options: unknown,
): Promise<void | LookupAddress | LookupAddress[]> {
let hints = 0;
let family = 0;
let all = false;
let dnsOrder = getDefaultDnsOrder();
// Parse arguments
if (hostname) {
validateString(hostname, "hostname");
}
if (isFamily(options)) {
validateOneOf(options, "family", validFamilies);
family = options;
} else if (!isLookupOptions(options)) {
throw new ERR_INVALID_ARG_TYPE("options", ["integer", "object"], options);
} else {
if (options?.hints != null) {
validateNumber(options.hints, "options.hints");
hints = options.hints >>> 0;
validateHints(hints);
}
if (options?.family != null) {
// Accept both numeric (0, 4, 6) and string ('IPv4', 'IPv6') family values
// to match Node.js behavior
switch (options.family) {
case "IPv4":
family = 4;
break;
case "IPv6":
family = 6;
break;
default:View on GitHub (pinned to a961cdec3b)
Solutions
- Pass the object form: dnsPromises.lookup(host, { family: 4 }).
- Coerce config values once at startup: family = Number(family), then wrap into the options object.
- Reject non-integer/non-object option values at the boundary with an isFamilyOrOptions guard.
Example fix
// before
dnsPromises.lookup(host, '4'); // family as string
// after
dnsPromises.lookup(host, { family: 4 });
// or: dnsPromises.lookup(host, 4); Defensive patterns
Strategy: validation
Validate before calling
function normalizeLookupOptions(o) {
if (o === undefined) return undefined;
if (Number.isInteger(o) && [0, 4, 6].includes(o)) return o;
if (typeof o === 'object' && o !== null && !Array.isArray(o)) return o;
throw new TypeError('options must be an integer family or an options object');
}
await dns.promises.lookup(host, normalizeLookupOptions(opts)); Type guard
const isFamilyOrOptions = (o) => (Number.isInteger(o) && [0, 4, 6].includes(o)) || (typeof o === 'object' && o !== null && !Array.isArray(o));
Try / catch
try {
await dnsPromises.lookup(host, opts);
} catch (err) {
if (err?.code === 'ERR_INVALID_ARG_TYPE' && err.message.includes('options')) {
return dnsPromises.lookup(host, {});
}
throw err;
} Prevention
- Never pass family as a string - wrap it as { family: 4 }.
- Validate config-driven options once at startup.
- Remember arrays and null are not valid lookup options.
When it happens
Trigger: dnsPromises.lookup('example.com', '4') or 'ipv6' (family as a string); lookup(host, ['A']); lookup(host, true); passing a parsed URL object as options.
Common situations: Config files that store family as text; env-var-driven options coerced to strings; code copied from dns.resolve()-style APIs where the second argument is a record-type string.
Related errors
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_ARG_TYPE
- ERR_INCOMPATIBLE_OPTION_PAIR
- ERR_MISSING_OPTION
AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20).
Data as JSON: /api/errors/dd71df38cccb835d.
Report an issue: GitHub.