{"record":{"id":"39328f9b262a84a9","repo":"CloakHQ/CloakBrowser","slug":"cloakbrowser-could-not-normalize-http-proxy-url","errorCode":null,"errorMessage":"[cloakbrowser] Could not normalize HTTP proxy URL, passing through unchanged: ${(e as Error).message}","messagePattern":"\\[cloakbrowser\\] Could not normalize HTTP proxy URL, passing through unchanged: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"js/src/proxy.ts","lineNumber":230,"sourceCode":"    if (encPass !== null) {\n      userinfoPart = `${encUser}:${encPass}@`;\n    } else if (encUser) {\n      userinfoPart = `${encUser}@`;\n    } else {\n      userinfoPart = \"\";\n    }\n    const result = `${scheme}://${userinfoPart}${hostAndRest}`;\n    const credsChanged = encUser !== rawUserEnc\n      || (hasPassword ? encPass !== rawPassEnc : false);\n    if (credsChanged) {\n      console.info(\n        \"[cloakbrowser] Auto URL-encoded HTTP proxy credentials (special \" +\n        \"characters detected). Pre-encode the URL to suppress this notice.\",\n      );\n    }\n    return result;\n  } catch (e) {\n    console.warn(`[cloakbrowser] Could not normalize HTTP proxy URL, passing through unchanged: ${(e as Error).message}`);\n    return normalized;\n  }\n}\n\n/**\n * Resolve proxy into Playwright option and/or Chrome args.\n *\n * Proxies with credentials (SOCKS5 or HTTP/HTTPS on supported platforms) are\n * passed via Chrome's --proxy-server flag with inline credentials, bypassing\n * Playwright's CDP auth interceptor which breaks on some proxies (#182).\n */\nexport function resolveProxyConfig(\n  proxy: string | ProxyDict | undefined,\n  browserVersion?: string,\n  licenseKey?: string,\n  releaseChannel?: string,\n): ProxyConfig {\n  if (!proxy) return { proxyArgs: [] };","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/proxy.ts#L212-L248","documentation":"An unexpected exception was thrown while normalizing an HTTP proxy URL (typically invalid percent-encoding or characters that break encode/decode operations). The function logs the underlying error message and falls back to passing the partially normalized URL through unchanged.","triggerScenarios":"Passing an http:// proxy string with invalid escape sequences (%ZZ), raw control characters, or other malformed structure into resolveProxy/resolveProxyConfig; the catch block returns the input unchanged.","commonSituations":"Proxy credentials copied with special characters ($, #, %, @) not encoded; environment variables with trailing newlines; URLs that were already double-encoded and break decodeURIComponent.","solutions":["Percent-encode username and password individually with encodeURIComponent before building the URL.","Sanitize the value: trim whitespace and verify it parses with new URL(...).","If the provider gives a ready-encoded URL, use it verbatim instead of concatenating raw credentials."],"exampleFix":"// before\nconst proxy = `http://user:pa#ss%zz@10.0.0.1:3128`;\n\n// after\nconst proxy = `http://${encodeURIComponent('user')}:${encodeURIComponent('pa#ss%zz')}@10.0.0.1:3128`;","handlingStrategy":"validation","validationCode":"function buildHttpProxy(user: string, pass: string, host: string, port: number): string {\n  return `http://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@${host}:${port}`;\n}","typeGuard":"const hasValidPercentEncoding = (u: string): boolean => { try { decodeURIComponent(u); return true; } catch { return false; } };","tryCatchPattern":null,"preventionTips":["Encode username/password components at construction time.","Never paste raw credentials with @ : % # / into a proxy URL string.","Keep proxy config in one builder function so encoding happens in exactly one place."],"tags":["proxy","http","url-encoding","fallback"],"backgroundTag":"malformed-proxy-url","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}