{"record":{"id":"f22154613afa2c9d","repo":"JuliusBrussee/caveman","slug":"unsupported-proxy-protocol-proxy-protocol","errorCode":null,"errorMessage":"unsupported proxy protocol: ${proxy.protocol}","messagePattern":"unsupported proxy protocol: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/proxy-fetch.ts","lineNumber":120,"sourceCode":"      : [\"http_proxy\", \"HTTP_PROXY\", \"all_proxy\", \"ALL_PROXY\"];\n  const configured = readEnv(env, names);\n  return configured ? parseProxyUrl(configured) : null;\n}\n\nfunction proxyAuthHeader(proxy: URL): OutgoingHttpHeaders {\n  if (!proxy.username && !proxy.password) return {};\n  const credentials = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`;\n  return { \"proxy-authorization\": `Basic ${Buffer.from(credentials).toString(\"base64\")}` };\n}\n\nfunction abortError(): Error {\n  return new DOMException(\"This operation was aborted\", \"AbortError\") as unknown as Error;\n}\n\nfunction proxyRequest(proxy: URL): typeof httpsRequest {\n  if (proxy.protocol === \"http:\") return httpRequest;\n  if (proxy.protocol === \"https:\") return httpsRequest;\n  throw new TypeError(`unsupported proxy protocol: ${proxy.protocol}`);\n}\n\n/**\n * Opens a CONNECT tunnel so TLS is negotiated with the target, not the proxy.\n *\n * Terminating TLS at the proxy would hand it the request and, for a signed\n * release download, the bytes we are about to trust.\n */\nfunction openTunnel(target: URL, proxy: URL, signal: AbortSignal | null): Promise<Socket> {\n  return new Promise((resolve, reject) => {\n    if (signal?.aborted) {\n      reject(abortError());\n      return;\n    }\n\n    let settled = false;\n    const finish = (error?: Error, socket?: Socket) => {\n      if (settled) {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/proxy-fetch.ts#L102-L138","documentation":"proxyRequest selects the Node http/https request factory based on the proxy URL's protocol. Only http: and https: proxies are supported; anything else (socks5:, ftp:, etc.) causes an immediate TypeError before any connection is attempted.","triggerScenarios":"Configuring a proxy URL whose protocol is not http: or https: — e.g. HTTPS_PROXY=socks5://host:1080 or a malformed proxy env var parsed into a URL with an unexpected scheme.","commonSituations":"Developers pointing HTTPS_PROXY/HTTP_PROXY at a SOCKS proxy (ssh -D tunnels, corporate SOCKS gateways); typos like 'socks5h://'; proxy URLs missing scheme so URL parsing yields odd protocols.","solutions":["Change the proxy to an HTTP(S) proxy: HTTP_PROXY=http://proxyhost:port (or https:// for a TLS proxy).","If you need SOCKS, run an HTTP proxy in front (e.g. `privoxy`, or `gost -L http://:8080 -F socks5://...`) and point the env var at it.","Check the protocol the URL actually parses to: `new URL(process.env.HTTPS_PROXY ?? '').protocol` and correct it.","Remove quotes/scheme typos from the proxy env var value."],"exampleFix":"// before\nHTTPS_PROXY=socks5://127.0.0.1:1080\n// after\nHTTPS_PROXY=http://127.0.0.1:8118  # local HTTP proxy (e.g. privoxy) fronting the SOCKS tunnel","handlingStrategy":"validation","validationCode":"const proxy = process.env.HTTPS_PROXY ? new URL(process.env.HTTPS_PROXY) : null;\nif (proxy && proxy.protocol !== \"http:\" && proxy.protocol !== \"https:\")\n  throw new Error(`Proxy must be http(s), got: ${proxy.protocol}`);","typeGuard":"function isHttpProxy(proxy: URL): boolean { return proxy.protocol === \"http:\" || proxy.protocol === \"https:\"; }","tryCatchPattern":"try {\n  await fetch(url);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes(\"unsupported proxy protocol\")) {\n    console.error(`Fix proxy env var: ${e.message} (only http:/https: supported)`);\n  } else throw e;\n}","preventionTips":["Only set HTTP(S)_PROXY to http:// or https:// URLs; never socks5://.","Validate proxy env vars at startup with new URL() and check .protocol.","Front SOCKS tunnels with an HTTP proxy (privoxy/gost) if SOCKS is required.","Document the proxy requirement for your team's dev environments."],"tags":["proxy","configuration","network","unsupported-protocol"],"backgroundTag":"unsupported-proxy-protocol","analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-31T22:10:17.934Z","contentChangedAt":"2026-08-31T22:10:17.934Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}