garrytan/gstack · error · ProxyConfigError
invalid proxy URL — bad port
Error message
invalid proxy URL — bad port
What it means
Thrown by parseProxyConfig when the port is not a valid integer in 1..65535. The port comes from url.port if present, otherwise a scheme default (80 for http, 443 for https, 1080 for socks5). An explicit out-of-range or non-numeric port is refused.
Source
Thrown at browse/src/proxy-config.ts:74
if (scheme !== 'socks5' && scheme !== 'http' && scheme !== 'https') {
throw new ProxyConfigError(
'use socks5://, http://, or https://',
`unsupported proxy scheme '${scheme}'`,
);
}
if (!url.hostname) {
throw new ProxyConfigError(
'expected scheme://[user:pass@]host:port',
`invalid proxy URL — missing host`,
);
}
const port = url.port
? parseInt(url.port, 10)
: (scheme === 'http' ? 80 : scheme === 'https' ? 443 : 1080);
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
throw new ProxyConfigError(
'expected scheme://[user:pass@]host:port',
`invalid proxy URL — bad port`,
);
}
const urlHasUser = !!url.username;
const urlHasPass = !!url.password;
const envHasUser = !!opts.envUser;
const envHasPass = !!opts.envPass;
const urlHasCreds = urlHasUser || urlHasPass;
const envHasCreds = envHasUser || envHasPass;
// D9 (codex correction): refuse on mixed sources. Silent override is a
// debugging trap — when a stale BROWSE_PROXY_USER from a prior session
// wins over a fresh --proxy URL, the user can't tell why.
if (urlHasCreds && envHasCreds) {
throw new ProxyConfigError(
'unset BROWSE_PROXY_USER/PASS or remove user:pass@ from --proxy',View on GitHub (pinned to 94993f7401)
Solutions
- Use a port in 1..65535 (common defaults: 1080 for socks5, 8080/3128 for http)
- Omit the port entirely to use the scheme default (80/443/1080)
- Double-check the proxy server's actual listening port with its operator or `ss -tlnp`
- Validate: `node -e "const p=+process.argv[1]; console.log(Number.isInteger(p)&&p>0&&p<=65535)" <port>`
Example fix
# before BROWSE_PROXY_URL=socks5://host:99999 # throws # after BROWSE_PROXY_URL=socks5://host:1080
Defensive patterns
Strategy: validation
Validate before calling
function isValidPort(s: string): boolean {
try {
const u = new URL(s);
const port = u.port ? parseInt(u.port, 10)
: (u.protocol === 'http:' ? 80 : u.protocol === 'https:' ? 443 : 1080);
return Number.isInteger(port) && port > 0 && port <= 65535;
} catch { return false; }
}
if (!isValidPort(proxyUrl)) {
throw new Error('Proxy port must be an integer in 1..65535');
} Type guard
function isIntegerPort(p: number): boolean {
return Number.isInteger(p) && p > 0 && p <= 65535;
} Try / catch
try {
parseProxyConfig(opts);
} catch (e) {
if (e instanceof ProxyConfigError && /bad port/.test(e.message)) {
console.error(`${e.message}. ${e.hint}`);
}
throw e;
} Prevention
- Stick to well-known ports (1080 for SOCKS5, 8080/3128 for HTTP)
- Omit the port to use the scheme default
- Confirm the proxy's listening port with `ss -tlnp` or its operator
- Validate the port as an integer in range in your config loader
When it happens
Trigger: Passing a proxy URL with port 0, a negative port, a port above 65535, or a non-numeric string in the port position.
Common situations: Typo in the port number (e.g., 99999); copy-paste truncation that left a partial port; ephemeral port picked out of range; confusion between display port and actual listening port.
Related errors
- invalid proxy URL — could not parse
- unsupported proxy scheme '${scheme}'
- invalid proxy URL — missing host
- proxy creds set in both env (BROWSE_PROXY_USER) and URL — pi
- API error (${response.status}): ${error.slice(0, 300)}
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/ba43fb9c1144c8af.
Report an issue: GitHub.