{"record":{"id":"8da1ed3170afc981","repo":"BigPizzaV3/CodexPlusPlus","slug":"base-url-8da1ed","errorCode":null,"errorMessage":"Base URL 缺少主机名","messagePattern":"Base URL 缺少主机名","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/routes.rs","lineNumber":778,"sourceCode":"        \"status\": \"ok\",\n        \"http_status\": http_status,\n        \"ok\": ok,\n        \"body_text\": body_text,\n        \"body_json\": body_json,\n    }))\n}\n\nfn validate_llm_proxy_url(raw: &str) -> anyhow::Result<reqwest::Url> {\n    let url = reqwest::Url::parse(raw.trim()).map_err(|_| anyhow::anyhow!(\"Base URL 格式无效\"))?;\n    if url.scheme() != \"https\" {\n        anyhow::bail!(\"Base URL 必须使用 HTTPS\");\n    }\n    if !url.username().is_empty() || url.password().is_some() {\n        anyhow::bail!(\"Base URL 不得包含用户名或密码\");\n    }\n    let host = url\n        .host_str()\n        .ok_or_else(|| anyhow::anyhow!(\"Base URL 缺少主机名\"))?;\n    if is_blocked_llm_proxy_host(host) {\n        anyhow::bail!(\"Base URL 不得指向本机或私有网络\");\n    }\n    Ok(url)\n}\n\nfn is_blocked_llm_proxy_host(host: &str) -> bool {\n    let host = host\n        .trim()\n        .trim_start_matches('[')\n        .trim_end_matches(']')\n        .to_lowercase();\n    if host.is_empty()\n        || host == \"localhost\"\n        || host.ends_with(\".localhost\")\n        || host.ends_with(\".local\")\n    {\n        return true;","sourceCodeStart":760,"sourceCodeEnd":796,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/routes.rs#L760-L796","documentation":"In validate_llm_proxy_url, after the URL parses and passes scheme/credential checks, url.host_str() must yield a host. This error fires when the URL has no host component (e.g. scheme-only or file-style URL), so the proxy endpoint would be unroutable.","triggerScenarios":"Thrown at crates/codex-plus-core/src/routes.rs:778 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Add the hostname to the Base URL, e.g. https://api.example.com","Do not use URLs without an authority component","Re-check the provider documentation for the correct endpoint format"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}