{"record":{"id":"88271a9d81f74cc8","repo":"tinyhumansai/openhuman","slug":"invalid-field-url-host-is-required","errorCode":null,"errorMessage":"Invalid {field} URL: host is required","messagePattern":"Invalid (.+?) URL: host is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/config/schema/proxy.rs","lineNumber":335,"sourceCode":"\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 {\n        std::env::remove_var(key);\n        std::env::remove_var(lowercase_key);\n    }\n}\n\nfn clear_proxy_env_pair(key: &str) {\n    std::env::remove_var(key);","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/config/schema/proxy.rs#L317-L353","documentation":"After a proxy URL parses successfully, validate_proxy_url requires a non-empty host (parsed.host_str() must be Some). A value like \"http://\" or \"socks5://\" has a scheme but no authority, so there is no server to dial and validation bails.","triggerScenarios":"[proxy] entries such as http_proxy=\"http://\", all_proxy=\"socks5h:///path\", or values whose host ended up in the path because the '//' after the scheme was omitted (e.g. \"http:8080\").","commonSituations":"Template placeholders collapsed to empty (http_proxy = \"http://{{host}}\" with the variable unset); truncation by env tooling; a typo deleting the host while editing; copy-pasting 'http://' from docs as a prefix example.","solutions":["Set a real host/IP with optional port: http://proxy.corp:3128 or socks5://127.0.0.1:1080","If a placeholder was left in the config, replace it with the actual proxy address","Remove proxy URL keys you do not use — absent keys are fine, present keys must be valid"],"exampleFix":"# before\nhttps_proxy = \"http://\"\n\n# after\nhttps_proxy = \"http://proxy.corp.example:3128\"","handlingStrategy":"validation","validationCode":"let parsed: reqwest::Url = value.parse()?;\nif parsed.host_str().map(str::is_empty).unwrap_or(true) {\n    return Err(format!(\"{field}: host is required, got '{value}'\"));\n}","typeGuard":null,"tryCatchPattern":"On config-load failure, match messages containing 'host is required' and print the [proxy] block with the offending key highlighted so the user fixes the right line.","preventionTips":["Never ship placeholder proxy URLs; comment the keys out instead","Validate proxy URL form (scheme + host) in settings UIs before persisting","After env-based overrides, diff the effective proxy config against expectations"],"tags":["proxy","url","host","validation"],"backgroundTag":"missing-url-host","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}