{"record":{"id":"40496deddea4a9d9","repo":"different-ai/openwork","slug":"proxy-must-include-host-and-port-e-g-http-user","errorCode":null,"errorMessage":"Proxy must include host and port, e.g. http://user:pass@host:8080 or socks5://host:1080.","messagePattern":"Proxy must include host and port, e\\.g\\. http://user:pass@host:8080 or socks5://host:1080\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/browser-panel.mjs","lineNumber":437,"sourceCode":"    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    };\n  }\n\n  async function setBrowserProxy(proxyInput) {","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/desktop/electron/browser-panel.mjs#L419-L455","documentation":"After the proxy string parses as a URL, parseBrowserProxyInput requires both hostname and port because Electron proxy rules need scheme://host:port. A URL without either part throws this hint-laden error.","triggerScenarios":"Passing 'proxy.corp.local' (implicit http://, no port → url.port empty), 'http://proxy:8080/some/path' is fine, but 'http://:8080' (empty hostname) or 'socks5://host' (no port) trigger it.","commonSituations":"Omitting the port because the proxy uses a default (80/443) — the parser still requires it explicitly; hostname lost after stripping a scheme incorrectly; env var containing just a hostname.","solutions":["Append the port: http://host:8080 instead of http://host or host","Ensure the hostname is present (not just :port)","Use the documented forms: http://user:pass@host:8080 or socks5://host:1080","If the proxy truly runs on a default port, still write the explicit port number"],"exampleFix":"// before\nproxy: 'socks5://proxy.corp.local'\n// after\nproxy: 'socks5://proxy.corp.local:1080'","handlingStrategy":"validation","validationCode":"function proxyHasHostAndPort(raw) {\n  const s = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw) ? raw : `http://${raw}`;\n  try { const u = new URL(s); return Boolean(u.hostname && u.port); } catch { return false; }\n}\nif (!proxyHasHostAndPort(userProxy)) alert('Proxy must include host and port, e.g. http://host:8080');","typeGuard":"function isCompleteProxyUrl(raw) {\n  try { const u = new URL(/^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw) ? raw : `http://${raw}`); return Boolean(u.hostname && u.port); }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  panel = createBrowserPanel({ proxy: proxyInput });\n} catch (e) {\n  if (e.message.startsWith('Proxy must include host and port')) {\n    // re-prompt with the documented examples\n  } else throw e;\n}","preventionTips":["Always include an explicit port, even for default ports (80/443)","Validate hostname and port presence in UI forms before saving config","Remember implicit http:// prefixing still requires a port to satisfy the parser","Use presets in config UI (http/https/socks5) that enforce host:port fields"],"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"}