denoland/deno · error · NodeTypeError

ERR_INVALID_ARG_VALUE

ERR_INVALID_ARG_VALUE

Error message

The argument 'hints' is invalid. Received ${hints}

What it means

dns.lookup()'s hints bitmask may only combine dns.constants.AI_ADDRCONFIG, AI_ALL and AI_V4MAPPED - validateHints() rejects any value with other bits set (hints & ~mask !== 0) with ERR_INVALID_ARG_VALUE. This mirrors Node: other AI_* flags (like AI_NUMERICHOST) are not accepted as lookup hints here.

Source

Thrown at ext/node/polyfills/internal/dns/utils.ts:435

    }

    this._handle.setLocalAddress(ipv4, ipv6);
  }
}

let defaultResolver = new Resolver();

function getDefaultResolver(): Resolver {
  return defaultResolver;
}

function setDefaultResolver<T extends Resolver>(resolver: T) {
  defaultResolver = resolver;
}

function validateHints(hints: number) {
  if ((hints & ~(AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED)) !== 0) {
    throw new ERR_INVALID_ARG_VALUE("hints", hints, "is invalid");
  }
}

let dnsOrder: string | undefined;

function ensureDnsOrder(): string {
  if (dnsOrder === undefined) {
    dnsOrder = getOptionValue("--dns-result-order") || "ipv4first";
  }
  return dnsOrder;
}

function getDefaultDnsOrder(): string {
  return ensureDnsOrder();
}

const validDnsOrders = ["verbatim", "ipv4first", "ipv6first"];

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Build hints only from the three allowed constants: hints: AI_ADDRCONFIG | AI_V4MAPPED.
  2. Omit hints entirely when you do not need them - undefined means 'none'.
  3. Validate user/config-provided hints against the mask before calling lookup.

Example fix

// before
dns.promises.lookup(host, { hints: 0xff });

// after
import { AI_ADDRCONFIG, AI_V4MAPPED } from 'node:dns/constants';
dns.promises.lookup(host, { hints: AI_ADDRCONFIG | AI_V4MAPPED });
Defensive patterns

Strategy: validation

Validate before calling

import { AI_ADDRCONFIG, AI_ALL, AI_V4MAPPED } from 'node:dns/constants';
const HINTS_MASK = AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED;

function validHints(h) {
  return h === undefined || (Number.isInteger(h) && (h & ~HINTS_MASK) === 0);
}
if (!validHints(opts.hints)) {
  throw new RangeError('hints may only combine AI_ADDRCONFIG, AI_ALL, AI_V4MAPPED');
}
await dns.promises.lookup(host, opts);

Type guard

import { AI_ADDRCONFIG, AI_ALL, AI_V4MAPPED } from 'node:dns/constants';
const isHintsMask = (h) =>
  Number.isInteger(h) && (h & ~(AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED)) === 0;

Try / catch

try {
  await dnsPromises.lookup(host, { hints });
} catch (err) {
  if (err?.code === 'ERR_INVALID_ARG_VALUE' && err.message.includes('hints')) {
    return dnsPromises.lookup(host, {}); // retry with no hints
  }
  throw err;
}

Prevention

When it happens

Trigger: lookup(host, { hints: 0xff }); hints: -1; OR-ing every dns.constants.AI_* flag together; numeric hint values copied from another platform's headers.

Common situations: Developers combining all AI_ constants 'to be safe'; porting C getaddrinfo code with raw flag numbers; config fields that let users pass arbitrary integers as hints.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/4257552886298d69. Report an issue: GitHub.