{"record":{"id":"a1d26e73cd41cf73","repo":"tinyhumansai/openhuman","slug":"invalid-field-url-scheme-scheme-allowed-ht","errorCode":null,"errorMessage":"Invalid {field} URL scheme '{scheme}'. Allowed: http, https, socks5, socks5h","messagePattern":"Invalid (.+?) URL scheme '(.+?)'\\. Allowed: http, https, socks5, socks5h","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/config/schema/proxy.rs","lineNumber":328,"sourceCode":"\n    if let Some(prefix) = selector.strip_suffix(\".*\") {\n        return service_key.starts_with(prefix)\n            && service_key\n                .strip_prefix(prefix)\n                .is_some_and(|suffix| suffix.starts_with('.'));\n    }\n\n    false\n}\n\nfn validate_proxy_url(field: &str, url: &str) -> Result<()> {\n    let parsed = reqwest::Url::parse(url)\n        .with_context(|| format!(\"Invalid {field} URL: '{url}' is not a valid URL\"))?;\n\n    match parsed.scheme() {\n        \"http\" | \"https\" | \"socks5\" | \"socks5h\" => {}\n        scheme => {\n            anyhow::bail!(\n                \"Invalid {field} URL scheme '{scheme}'. Allowed: http, https, socks5, socks5h\"\n            );\n        }\n    }\n\n    if parsed.host_str().is_none() {\n        anyhow::bail!(\"Invalid {field} URL: host is required\");\n    }\n\n    Ok(())\n}\n\nfn set_proxy_env_pair(key: &str, value: Option<&str>) {\n    let lowercase_key = key.to_ascii_lowercase();\n    if let Some(value) = value.and_then(|candidate| normalize_proxy_url_option(Some(candidate))) {\n        std::env::set_var(key, &value);\n        std::env::set_var(lowercase_key, value);\n    } else {","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/config/schema/proxy.rs#L310-L346","documentation":"validate_proxy_url parses each proxy URL (http_proxy/https_proxy/all_proxy) with reqwest::Url and rejects any scheme other than http, https, socks5 or socks5h — the HTTP client stack only speaks those proxy protocols. Note that a scheme-less value like \"127.0.0.1:7890\" parses with '127.0.0.1' as the scheme and lands on this same error.","triggerScenarios":"Setting http_proxy=\"ftp://proxy:21\", all_proxy=\"socks4://127.0.0.1:1080\", or a bare host:port like \"127.0.0.1:7890\" in [proxy] config or env overrides; validation runs at config load.","commonSituations":"Copy-pasting a SOCKS4 or SSH tunnel endpoint; forgetting the http:// prefix for a local proxy (Clash/V2Ray style defaults); using ws:// for a tunnel; typos like 'socks5H://' (scheme matching is lowercase).","solutions":["Prefix the value with an allowed scheme: http://, https://, socks5://, or socks5h:// (e.g. http://127.0.0.1:7890)","For SOCKS proxies use socks5:// (local DNS) or socks5h:// (DNS resolved by the proxy)","If the endpoint is ftp:// or ssh://, it is not an HTTP proxy — terminate it locally first and point the config at that local http/socks5 listener"],"exampleFix":"# before\nhttp_proxy = \"127.0.0.1:7890\"\n\n# after\nhttp_proxy = \"http://127.0.0.1:7890\"","handlingStrategy":"validation","validationCode":"fn check_proxy_url(field: &str, url: &str) -> Result<(), String> {\n    let parsed: reqwest::Url = url.parse().map_err(|e| format!(\"{field}: unparseable: {e}\"))?;\n    match parsed.scheme() {\n        \"http\" | \"https\" | \"socks5\" | \"socks5h\" => Ok(()),\n        s => Err(format!(\"{field}: scheme '{s}' not allowed (http/https/socks5/socks5h)\")),\n    }\n}","typeGuard":null,"tryCatchPattern":"Catch the config-load error; when the message contains 'URL scheme', echo the offending field name and the four allowed schemes back to the user rather than failing silently.","preventionTips":["Always write proxy URLs fully qualified, including the scheme","Validate the scheme in settings UIs before save","Remember scheme matching is lowercase — socks5h works, SOCKS5H does not"],"tags":["proxy","url","scheme","validation"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}