denoland/deno · error · NodeTypeError

ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

Error message

The "proxyEnv" argument must be an instance of Object. Received ${input}

What it means

http.setGlobalProxyFromEnv(input) accepts either no argument (then it reads HTTP_PROXY/HTTPS_PROXY/NO_PROXY from the process environment) or a plain object of env-like values. Passing any defined non-object - array, string, number - throws ERR_INVALID_ARG_TYPE for 'proxyEnv'. Note null is also rejected here because isPlainObject(null) is false (unlike the Agent path, which tolerates null).

Source

Thrown at ext/node/polyfills/_http_proxy.js:393

  if (!enabled) return;
  // Use "env" mode so an invalid HTTP_PROXY surfaces as TypeError: Invalid URL,
  // matching Node v24's behavior at request time. The error propagates out
  // through resolveAgentProxyConfig and surfaces on the offending request.
  const cfg = buildProxyConfig(env, "env");
  if (cfg) globalProxyConfig = cfg;
}

function getGlobalProxyConfig() {
  maybeInitFromEnv();
  return globalProxyConfig;
}

function setGlobalProxyFromEnv(input) {
  let env;
  if (input === undefined) {
    env = readPrivilegedEnv();
  } else if (!isPlainObject(input)) {
    throw new ERR_INVALID_ARG_TYPE(
      "proxyEnv",
      "Object",
      input,
    );
  } else {
    env = input;
  }
  // Calling setGlobalProxyFromEnv replaces any NODE_USE_ENV_PROXY-derived
  // state; ensure that read-once gate is closed.
  try {
    maybeInitFromEnv();
  } catch {
    // Env-derived init may throw on invalid URLs, but the explicit caller
    // is replacing it anyway - swallow so we can install the new config.
  }
  initializedFromEnv = true;
  const newConfig = buildProxyConfig(env, "strict");
  const prev = globalProxyConfig;

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Pass a plain object: setGlobalProxyFromEnv({ http_proxy: 'http://proxy:8080' })
  2. Call it with no argument to read the real process environment
  3. Guard nullable config: `if (cfg) http.setGlobalProxyFromEnv(cfg)`

Example fix

// before
http.setGlobalProxyFromEnv(proxyUrl); // string -> throws ERR_INVALID_ARG_TYPE

// after
http.setGlobalProxyFromEnv({ http_proxy: proxyUrl, https_proxy: proxyUrl });
Defensive patterns

Strategy: type-guard

Validate before calling

function isPlainObject(v: unknown): v is Record<string, unknown> {
  return !!v && typeof v === 'object' && !Array.isArray(v);
}
if (cfg === undefined) http.setGlobalProxyFromEnv();
else if (isPlainObject(cfg)) http.setGlobalProxyFromEnv(cfg as Record<string, string>);
else throw new Error('proxy config must be a plain object');

Type guard

function isProxyEnvObject(v: unknown): v is Record<string, string | undefined> {
  return v === undefined || (!!v && typeof v === 'object' && !Array.isArray(v));
}

Try / catch

try {
  http.setGlobalProxyFromEnv(cfg);
} catch (e) {
  if (e?.code === 'ERR_INVALID_ARG_TYPE' && /proxyEnv/.test(e.message)) {
    http.setGlobalProxyFromEnv({ https_proxy: String(cfg) }); // coerce single URL
  } else throw e;
}

Prevention

When it happens

Trigger: http.setGlobalProxyFromEnv('http://proxy:8080') (passing a URL string), setGlobalProxyFromEnv(['http_proxy=x']) (array), or setGlobalProxyFromEnv(null).

Common situations: Assuming the API takes a URL; forwarding a possibly-null config field into the call.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/a3240b3678d63be3. Report an issue: GitHub.