{"record":{"id":"4ef9362f5abc5d91","repo":"denoland/deno","slug":"invalid-url-raw","errorCode":null,"errorMessage":"Invalid URL: ${raw}","messagePattern":"Invalid URL: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"critical","filePath":"ext/node/polyfills/_http_proxy.js","lineNumber":108,"sourceCode":"}\n\nfunction 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    }","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/_http_proxy.js#L90-L126","documentation":"In the node:http proxy support, parseProxyUrl validates values read from proxy environment variables (http_proxy/HTTP_PROXY, https_proxy/HTTPS_PROXY). In 'env' mode - active when NODE_USE_ENV_PROXY=1 or --use-env-proxy - a present-but-non-string value throws TypeError('Invalid URL: <value>'), mirroring whatwg URL constructor semantics that Node v24 surfaces at request time. The error propagates through resolveAgentProxyConfig and lands on the first request that needs the proxy.","triggerScenarios":"NODE_USE_ENV_PROXY=1 with an env-like source (or buildProxyConfig(env, 'env')) where http_proxy is a non-string non-empty value, e.g. a number or boolean injected programmatically; then any http request triggers maybeInitFromEnv and throws.","commonSituations":"Programmatically seeded process.env/privileged env with non-string values; test harnesses passing objects where strings belong; tooling that copies env JSON verbatim into the runtime; virtually impossible via a real shell, which only produces string env values.","solutions":["Ensure proxy env vars are strings: set them as String(value) or via a proper shell export.","Unset the malformed variable (or set it to empty string, which is treated as 'no proxy') so requests go direct.","If you inject env programmatically, validate http_proxy/https_proxy/no_proxy with typeof === 'string' before startup."],"exampleFix":"// before\nDeno.env.set('HTTP_PROXY', 123 as any); // non-string\n// NODE_USE_ENV_PROXY=1 -> first request throws TypeError\n\n// after\nDeno.env.set('HTTP_PROXY', 'http://proxy.local:8080');","handlingStrategy":"validation","validationCode":"function assertProxyEnvStrings(env) {\n  for (const k of ['http_proxy', 'HTTP_PROXY', 'https_proxy', 'HTTPS_PROXY']) {\n    const v = env[k];\n    if (v === undefined || v === '') continue;\n    if (typeof v !== 'string') throw new Error(`${k} must be a string, got ${typeof v}`);\n    new URL(v); // parseability pre-check\n  }\n}\nassertProxyEnvStrings(Deno.env.toObject());","typeGuard":null,"tryCatchPattern":"try {\n  http.get('http://example.com/', cb);\n} catch (err) {\n  if (err instanceof TypeError && String(err.message).startsWith('Invalid URL')) {\n    // proxy env var is malformed: fix/unset HTTP(S)_PROXY, then retry\n  } else throw err;\n}","preventionTips":["Set proxy variables only as full URL strings via shell exports.","Validate injected env values (typeof string + URL parse) at startup before NODE_USE_ENV_PROXY matters.","An empty-string value means 'no proxy' - prefer that over deleting when going direct."],"tags":["http","node-compat","proxy","environment","config"],"backgroundTag":"invalid-proxy-url","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"}