{"record":{"id":"4be7d864d0ab09dc","repo":"denoland/deno","slug":"err-proxy-invalid-config","errorCode":"ERR_PROXY_INVALID_CONFIG","errorMessage":"Invalid proxy URL for ${kind}: must be a string","messagePattern":"Invalid proxy URL for (.+?): must be a string","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_http_proxy.js","lineNumber":110,"sourceCode":"function readEnvKey(env, keys) {\n  for (let i = 0; i < keys.length; i++) {\n    const k = keys[i];\n    if (env[k] !== undefined && env[k] !== \"\") {\n      return env[k];\n    }\n  }\n  return undefined;\n}\n\nconst CRLF_RE = new SafeRegExp(/[\\r\\n]/);\n\nfunction parseProxyUrl(raw, kind, mode) {\n  if (raw === undefined || raw === null || raw === \"\") return null;\n  if (typeof raw !== \"string\") {\n    if (mode === \"env\") {\n      throw new TypeError(`Invalid URL: ${raw}`);\n    }\n    throw new ERR_PROXY_INVALID_CONFIG(\n      `Invalid proxy URL for ${kind}: must be a string`,\n    );\n  }\n  // CRLF injection guard - check raw string before URL parsing strips them.\n  // Matches Node's CRLF rejection in the proxy URL validator. We surface this\n  // even for env-derived URLs so the auth tests get the expected error class.\n  if (RegExpPrototypeExec(CRLF_RE, raw) !== null) {\n    throw new ERR_PROXY_INVALID_CONFIG(`Invalid proxy URL: ${raw}`);\n  }\n  let url;\n  try {\n    url = new URL(raw);\n  } catch {\n    if (mode === \"env\") {\n      throw new TypeError(`Invalid URL: ${raw}`);\n    }\n    throw new ERR_PROXY_INVALID_CONFIG(`Invalid proxy URL: ${raw}`);\n  }","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/_http_proxy.js#L92-L128","documentation":"In 'strict' mode - used by setGlobalProxyFromEnv(envObject) and new http.Agent({ proxyEnv }) - parseProxyUrl requires proxy values to be strings. A present, non-empty, non-string value (number, boolean, object) throws ERR_PROXY_INVALID_CONFIG with 'Invalid proxy URL for <kind>: must be a string', naming which variable (http_proxy/https_proxy) is at fault.","triggerScenarios":"setGlobalProxyFromEnv({ http_proxy: 8080 }); new http.Agent({ proxyEnv: { https_proxy: true } }); JSON config deserialized into the env object with numeric ports or booleans instead of full URL strings.","commonSituations":"Config files storing the proxy as host:port pieces or numbers and assembling the object without stringification; feature flags (true/false) accidentally placed in the proxyEnv slot; environment snapshots from tools that preserve original JS types.","solutions":["Provide full URL strings: { http_proxy: 'http://proxy.local:8080' }.","Stringify when building the object programmatically: proxyEnv: { http_proxy: String(cfg.proxyUrl) }.","Omit the key entirely (or empty string) when no proxy should be configured."],"exampleFix":"// before\nsetGlobalProxyFromEnv({ http_proxy: 8080 }); // number -> ERR_PROXY_INVALID_CONFIG\n\n// after\nsetGlobalProxyFromEnv({ http_proxy: 'http://127.0.0.1:8080' });","handlingStrategy":"validation","validationCode":"function normalizeProxyEnv(cfg) {\n  const out = {};\n  for (const k of ['http_proxy', 'https_proxy']) {\n    const v = cfg[k];\n    if (v === undefined || v === null || v === '') continue;\n    out[k] = String(v); // reject non-strings before the library does\n    if (typeof v !== 'string') throw new Error(`${k} must be a string`);\n  }\n  return out;\n}\nsetGlobalProxyFromEnv(normalizeProxyEnv(config));","typeGuard":"function isProxyEnvObject(o) {\n  return o !== null && typeof o === 'object' && !Array.isArray(o) &&\n    Object.values(o).every((v) => v === undefined || v === '' || typeof v === 'string');\n}","tryCatchPattern":"try {\n  const restore = setGlobalProxyFromEnv(env);\n} catch (err) {\n  if (err.code === 'ERR_PROXY_INVALID_CONFIG') {\n    // message names the offending variable: log it, fix config, keep previous proxy via restore semantics\n  } else throw err;\n}","preventionTips":["Always pass full URL strings ('http://host:port') in proxyEnv objects.","Stringify config-sourced values when assembling the object.","Validate the shape once at config load; fail fast with the key name."],"tags":["http","node-compat","proxy","config","argument-validation"],"backgroundTag":"invalid-proxy-configuration","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}