different-ai/openwork · error · Error

Proxy must include host and port, e.g. http://user:pass@host

Error message

Proxy must include host and port, e.g. http://user:pass@host:8080 or socks5://host:1080.

What it means

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.

Source

Thrown at apps/desktop/electron/browser-panel.mjs:437

    if (!envMatch) return raw;
    const key = `OPENWORK_BROWSER_PROXY_${envMatch[1].toUpperCase()}`;
    const value = String(process.env[key] ?? "").trim();
    if (!value) throw new Error(`No proxy configured: set the ${key} environment variable to a proxy URL.`);
    return value;
  }

  function parseBrowserProxyInput(input) {
    const raw = resolveBrowserProxyInput(input);
    if (!raw) return null;
    const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(raw) ? raw : `http://${raw}`;
    let url;
    try {
      url = new URL(withScheme);
    } catch {
      throw new Error(`Invalid proxy URL: ${raw}`);
    }
    if (!url.hostname || !url.port) {
      throw new Error("Proxy must include host and port, e.g. http://user:pass@host:8080 or socks5://host:1080.");
    }
    const scheme = url.protocol.replace(/:$/, "").toLowerCase();
    return {
      rules: `${scheme}://${url.hostname}:${url.port}`,
      username: decodeURIComponent(url.username),
      password: decodeURIComponent(url.password),
    };
  }

  function browserProxyState() {
    return {
      proxy: browserProxy
        ? { rules: browserProxy.rules, authenticated: Boolean(browserProxy.username) }
        : null,
    };
  }

  async function setBrowserProxy(proxyInput) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Append the port: http://host:8080 instead of http://host or host
  2. Ensure the hostname is present (not just :port)
  3. Use the documented forms: http://user:pass@host:8080 or socks5://host:1080
  4. If the proxy truly runs on a default port, still write the explicit port number

Example fix

// before
proxy: 'socks5://proxy.corp.local'
// after
proxy: 'socks5://proxy.corp.local:1080'
Defensive patterns

Strategy: validation

Validate before calling

function proxyHasHostAndPort(raw) {
  const s = /^[a-z][a-z0-9+.-]*:\/\//i.test(raw) ? raw : `http://${raw}`;
  try { const u = new URL(s); return Boolean(u.hostname && u.port); } catch { return false; }
}
if (!proxyHasHostAndPort(userProxy)) alert('Proxy must include host and port, e.g. http://host:8080');

Type guard

function isCompleteProxyUrl(raw) {
  try { const u = new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(raw) ? raw : `http://${raw}`); return Boolean(u.hostname && u.port); }
  catch { return false; }
}

Try / catch

try {
  panel = createBrowserPanel({ proxy: proxyInput });
} catch (e) {
  if (e.message.startsWith('Proxy must include host and port')) {
    // re-prompt with the documented examples
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/40496deddea4a9d9. Report an issue: GitHub.