{"record":{"id":"895e37c9402b9513","repo":"different-ai/openwork","slug":"invalid-proxy-url-raw","errorCode":null,"errorMessage":"Invalid proxy URL: ${raw}","messagePattern":"Invalid proxy URL: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/browser-panel.mjs","lineNumber":434,"sourceCode":"  function resolveBrowserProxyInput(input) {\n    const raw = String(input ?? \"\").trim();\n    const envMatch = raw.match(/^env:([A-Za-z0-9_]+)$/i);\n    if (!envMatch) return raw;\n    const key = `OPENWORK_BROWSER_PROXY_${envMatch[1].toUpperCase()}`;\n    const value = String(process.env[key] ?? \"\").trim();\n    if (!value) throw new Error(`No proxy configured: set the ${key} environment variable to a proxy URL.`);\n    return value;\n  }\n\n  function parseBrowserProxyInput(input) {\n    const raw = resolveBrowserProxyInput(input);\n    if (!raw) return null;\n    const withScheme = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw) ? raw : `http://${raw}`;\n    let url;\n    try {\n      url = new URL(withScheme);\n    } catch {\n      throw new Error(`Invalid proxy URL: ${raw}`);\n    }\n    if (!url.hostname || !url.port) {\n      throw new Error(\"Proxy must include host and port, e.g. http://user:pass@host:8080 or socks5://host:1080.\");\n    }\n    const scheme = url.protocol.replace(/:$/, \"\").toLowerCase();\n    return {\n      rules: `${scheme}://${url.hostname}:${url.port}`,\n      username: decodeURIComponent(url.username),\n      password: decodeURIComponent(url.password),\n    };\n  }\n\n  function browserProxyState() {\n    return {\n      proxy: browserProxy\n        ? { rules: browserProxy.rules, authenticated: Boolean(browserProxy.username) }\n        : null,\n    };","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/browser-panel.mjs#L416-L452","documentation":"parseBrowserProxyInput prepends http:// if no scheme is present, then runs the result through the URL constructor; if parsing fails the raw input is thrown back in this error. The proxy string is not a parsable URL.","triggerScenarios":"Passing malformed proxy values like 'http://host' (unparseable due to bad characters), 'host:port:extra', strings with spaces, or an env-resolved value that is not a URL (e.g. a bare 'proxy.corp' with no host:port shape the URL parser accepts).","commonSituations":"Copy-paste errors with hidden whitespace or smart quotes; forgetting both scheme and port ('myproxy.corp' becomes http://myproxy.corp which has no port — that throws the NEXT error, so this one is usually true syntax garbage like 'http://'); quoting issues in shell env vars.","solutions":["Provide a full valid URL, e.g. http://user:pass@host:8080 or socks5://host:1080","Trim surrounding whitespace and quotes from the configured value","If omitting scheme, use the host:port form so the implicit http:// prefix yields a valid URL","Inspect the resolved env value (when using env:VAR) — the bad string may come from the variable, not the config"],"exampleFix":"// before\nproxy: 'http://'\n// after\nproxy: 'http://proxy.corp.local:8080'","handlingStrategy":"validation","validationCode":"function isValidProxyInput(raw) {\n  let s = String(raw ?? '').trim();\n  if (!s) return true;\n  if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(s)) s = `http://${s}`;\n  try { const u = new URL(s); return Boolean(u.hostname && u.port); } catch { return false; }\n}","typeGuard":"function isParsableProxyUrl(raw) {\n  try {\n    const s = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw) ? raw : `http://${raw}`;\n    return new URL(s) instanceof URL;\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  panel = createBrowserPanel({ proxy: proxyInput });\n} catch (e) {\n  if (e.message.startsWith('Invalid proxy URL:')) {\n    // show the offending value and the expected format, disable browser panel\n  } else throw e;\n}","preventionTips":["Always test the proxy string with new URL() before configuring","Strip quotes/whitespace from env-sourced values","Use the documented forms: http://user:pass@host:8080 or socks5://host:1080","Don't include bare schemes without host (e.g. 'http://')"],"tags":["proxy","url-parsing","validation","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}