{"record":{"id":"07a71bd55e358430","repo":"xai-org/grok-build","slug":"invalid-proxy-port-in-url","errorCode":null,"errorMessage":"Invalid proxy port in '{url}'","messagePattern":"Invalid proxy port in '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/agent/proxy.rs","lineNumber":235,"sourceCode":"///\n/// Accepted formats:\n/// - `http://host:port`\n/// - `http://host` (defaults to port 80)\n/// - `host:port`\nfn parse_proxy_url(url: &str) -> anyhow::Result<(String, u16)> {\n    // Strip scheme if present.\n    let without_scheme = url\n        .strip_prefix(\"http://\")\n        .or_else(|| url.strip_prefix(\"https://\"))\n        .unwrap_or(url);\n\n    // Strip trailing path/slash.\n    let authority = without_scheme.split('/').next().unwrap_or(without_scheme);\n\n    if let Some((host, port_str)) = authority.rsplit_once(':') {\n        let port: u16 = port_str\n            .parse()\n            .map_err(|_| anyhow::anyhow!(\"Invalid proxy port in '{url}'\"))?;\n        Ok((host.to_string(), port))\n    } else {\n        // No port — default to 80 for HTTP proxies.\n        Ok((authority.to_string(), 80))\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Tests\n// ---------------------------------------------------------------------------\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use tokio::io::{AsyncReadExt, AsyncWriteExt};\n\n    // ===== parse_proxy_url =====\n","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/agent/proxy.rs#L217-L253","documentation":"parse_proxy_url splits a proxy URL into host and port. When an explicit port is present after the last ':' it is parsed as u16; if parsing fails (non-numeric, empty, or out of range) this error is thrown.","triggerScenarios":"PROXY_URL like 'http://proxy:abc', 'proxy.corp:', 'http://proxy:99999' (>65535), or any string with a colon followed by garbage after the scheme is stripped.","commonSituations":"Typo in proxy config, shell-expanded empty variable producing 'http://proxy:', copy-pasting a URL that includes ':/', or IPv6 addresses whose extra colons confuse the naive rsplit_once(':') split.","solutions":["Check the proxy URL env/config value and fix the port to a valid number 1-65535","Omit the port entirely to default to 80","For IPv6 proxies use a form the parser accepts (bracketed host without stray colons after authority extraction) or fix the parser to use url::Url parsing","Add a unit test for the failing URL string before changing config"],"exampleFix":"// before\nlet proxy = \"http://proxy.corp:8.8.8.8\"; // invalid port\n// after\nlet proxy = \"http://proxy.corp:8080\";","handlingStrategy":"validation","validationCode":"fn valid_proxy(s: &str) -> bool {\n    let authority = s.trim_start_matches(\"http://\").trim_start_matches(\"https://\").split('/').next().unwrap_or(\"\");\n    match authority.rsplit_once(':') {\n        Some((_, p)) => p.parse::<u16>().is_ok(),\n        None => !authority.is_empty(),\n    }\n}\n// call before passing proxy_url to the library","typeGuard":null,"tryCatchPattern":"match parse_proxy_url(&url) {\n    Ok((host, port)) => { /* ... */ }\n    Err(e) => eprintln!(\"fix proxy config: {e}\"),\n}","preventionTips":["Validate proxy URLs at config load time, not at connect time","Prefer url::Url::parse over manual string splitting for proxy config","Document that omitting the port defaults to 80"],"tags":["proxy","config","parsing"],"backgroundTag":"invalid-proxy-port","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}