{"record":{"id":"acc47800b8563d70","repo":"pnpm/pnpm","slug":"invalid-proxy","errorCode":"INVALID_PROXY","errorMessage":"Couldn't parse proxy URL","messagePattern":"Couldn't parse proxy URL","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/network/fetch/src/dispatcher.ts","lineNumber":171,"sourceCode":"    opts.ca ||\n    opts.cert ||\n    opts.key ||\n    opts.localAddress ||\n    opts.strictSsl === false ||\n    hasClientCertificates(opts.clientCertificates) ||\n    opts.maxSockets\n  )\n}\n\nfunction parseProxyUrl (proxy: string, protocol: string): URL {\n  let proxyUrl = proxy\n  if (!proxyUrl.includes('://')) {\n    proxyUrl = `${protocol}//${proxyUrl}`\n  }\n  try {\n    return new URL(proxyUrl)\n  } catch {\n    throw new PnpmError('INVALID_PROXY', \"Couldn't parse proxy URL\", {\n      hint: 'If your proxy URL contains a username and password, make sure to URL-encode them ' +\n        '(you may use the encodeURIComponent function). For instance, ' +\n        'https-proxy=https://use%21r:pas%2As@my.proxy:1234/foo. ' +\n        'Do not encode the colon (:) between the username and password.',\n    })\n  }\n}\n\n\nfunction getSocksProxyType (protocol: string): 4 | 5 {\n  switch (protocol.replace(':', '')) {\n    case 'socks4':\n    case 'socks4a':\n      return 4\n    default:\n      return 5\n  }\n}","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/network/fetch/src/dispatcher.ts#L153-L189","documentation":"parseProxyUrl normalizes the configured proxy value (https-proxy/proxy settings or environment) by prepending the protocol when the value lacks '://', then parses it with the URL constructor. Any construction failure becomes INVALID_PROXY, with a hint that credentials embedded in the URL must be percent-encoded (everything except the colon between user and password).","triggerScenarios":"A proxy value that is not a valid absolute URL after normalization: unencoded reserved characters (!, @, :, /, *) in the userinfo, a broken scheme like 'http//host', or stray whitespace in the setting.","commonSituations":"HTTPS_PROXY / https-proxy containing a password pasted verbatim from a password manager; CI secrets with special characters; hand-typed proxy URLs missing a scheme or port.","solutions":["Percent-encode the username and password in the proxy URL (encodeURIComponent), keeping the literal colon between them — exactly as the error hint describes","Fix the scheme and shape: http://host:port, https://host:port, or socks5://host:port","Unset or correct the proxy env vars (HTTPS_PROXY, HTTP_PROXY, ALL_PROXY) and the pnpm config if no proxy is intended","Where possible, keep credentials out of the URL entirely"],"exampleFix":"# before — password contains ! and * unencoded\nhttps-proxy=https://use!r:pas*s@my.proxy:1234\n\n# after — percent-encoded userinfo, colon kept literal\nhttps-proxy=https://use%21r:pas%2As@my.proxy:1234","handlingStrategy":"validation","validationCode":"function isValidProxyUrl (proxy: string, protocol = 'https:'): boolean {\n  try {\n    new URL(proxy.includes('://') ? proxy : `${protocol}//${proxy}`)\n    return true\n  } catch {\n    return false\n  }\n}\n\nfor (const candidate of [process.env.HTTPS_PROXY, process.env.HTTP_PROXY, config['https-proxy']]) {\n  if (candidate && !isValidProxyUrl(candidate)) {\n    // percent-encode userinfo or fix the scheme before running pnpm\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  createDispatcher(...)\n} catch (err) {\n  if (err instanceof PnpmError && err.code === 'INVALID_PROXY') {\n    // follow the embedded hint: encode credentials, keep the user:pass colon literal\n  }\n  throw err\n}","preventionTips":["Always percent-encode usernames and passwords placed in proxy URLs (encodeURIComponent), keeping only the separating colon literal","Validate proxy settings from env and config at startup in CI, before the first network call","Store proxy credentials outside the URL where your tooling allows it"],"tags":["network","proxy","url","config"],"backgroundTag":"invalid-proxy-url","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}