{"record":{"id":"4eb24fa6d0eade56","repo":"CloakHQ/CloakBrowser","slug":"cloakbrowser-could-not-normalize-socks5-proxy-ur","errorCode":null,"errorMessage":"[cloakbrowser] Could not normalize SOCKS5 proxy URL, passing through unchanged: ${(e as Error).message}","messagePattern":"\\[cloakbrowser\\] Could not normalize SOCKS5 proxy URL, passing through unchanged: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"js/src/proxy.ts","lineNumber":155,"sourceCode":"    const encUser = rawUserEnc ? encodeURIComponent(lenientDecodeURIComponent(rawUserEnc)) : \"\";\n    const encPass = hasPassword\n      ? (rawPassEnc ? encodeURIComponent(lenientDecodeURIComponent(rawPassEnc)) : \"\")\n      : null;\n    const normalized = assembleSocksUrl(scheme, encUser, encPass, hostAndRest);\n    // Compare credentials, not the full URL: keeps the log condition focused\n    // on real encoding work, not cosmetic differences (parity with the Python\n    // implementation, which has to skip urlparse's hostname lowercasing).\n    const credsChanged = encUser !== rawUserEnc\n      || (hasPassword ? encPass !== rawPassEnc : false);\n    if (credsChanged) {\n      console.info(\n        \"[cloakbrowser] Auto URL-encoded SOCKS5 proxy credentials (special \" +\n        \"characters detected). Pre-encode the URL to suppress this notice.\",\n      );\n    }\n    return normalized;\n  } catch (e) {\n    console.warn(`[cloakbrowser] Could not normalize SOCKS5 proxy URL, passing through unchanged: ${(e as Error).message}`);\n    return urlStr;\n  }\n}\n\nfunction hasCredentials(proxy: string | ProxyDict): boolean {\n  if (typeof proxy === \"string\") return proxy.includes(\"@\");\n  return !!proxy.username;\n}\n\n/**\n * Reconstruct an HTTP(S) proxy URL with inline credentials from a proxy dict.\n */\nexport function reconstructHttpUrl(proxy: ProxyDict): string {\n  if (!proxy.username) return proxy.server;\n  const url = new URL(ensureProxyScheme(proxy.server));\n  url.username = encodeURIComponent(proxy.username);\n  if (proxy.password) url.password = encodeURIComponent(proxy.password);\n  return url.href.replace(/\\/$/, \"\");","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/proxy.ts#L137-L173","documentation":"An unexpected exception escaped while normalizing a SOCKS5 proxy URL (e.g. a malformed URL that made built-ins like decodeURIComponent/URI encoding throw). The function catches it, logs the underlying message, and passes your original string through untouched — so the raw URL goes to Chromium and may fail later.","triggerScenarios":"Passing a SOCKS5 URL with invalid percent-encoding (e.g. %ZZ in credentials), control characters, or other structural oddities that throw inside the try block of normalizeSocksStringUrl; the catch returns urlStr verbatim.","commonSituations":"Credentials with raw special characters ($, @, :, %, spaces) pasted from a proxy provider dashboard; double-encoded URLs; strings containing newlines from env vars or config files.","solutions":["Pre-encode the whole proxy URL yourself with encodeURIComponent on user/password parts (the warning for auto-encoding then disappears too).","Validate/decode the URL before passing it: ensure it parses with new URL(...) and percent-sequences are valid.","Check for stray whitespace/newlines around the value from env vars or .env files."],"exampleFix":"// before\nconst proxy = `socks5://myuser:p@ss:w%ord@1.2.3.4:1080`;\n\n// after\nconst u = encodeURIComponent('myuser');\nconst p = encodeURIComponent('p@ss:w%ord');\nconst proxy = `socks5://${u}:${p}@1.2.3.4:1080`;","handlingStrategy":"validation","validationCode":"function safeSocksUrl(user: string, pass: string, host: string, port: number): string {\n  return `socks5://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@${host}:${port}`;\n}\nconst proxy = safeSocksUrl('user', 'p@ss%', '1.2.3.4', 1080); // never throws in normalizer","typeGuard":"const hasValidPercentEncoding = (u: string): boolean => { try { decodeURIComponent(u); return true; } catch { return false; } };","tryCatchPattern":null,"preventionTips":["Always percent-encode credentials yourself; don't rely on the auto-encoder after an exception path.","Reject proxy strings containing whitespace/control characters before passing them on.","Unit-test proxy-URL construction against special-character credentials."],"tags":["proxy","socks5","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"}