{"record":{"id":"a0e5a5c3a4291dea","repo":"Hmbown/CodeWhale","slug":"unsupported-z-ai-web-search-endpoint-base-url","errorCode":null,"errorMessage":"unsupported Z.AI web-search endpoint: {base_url}","messagePattern":"unsupported Z\\.AI web-search endpoint: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/client/provider_native_search/zai.rs","lineNumber":15,"sourceCode":"//! Z.AI and Zhipu structured Web Search API contracts.\n\nuse anyhow::{Result, bail};\nuse serde_json::{Value, json};\n\nuse super::{\n    ProviderNativeSearchRequest, ProviderNativeSearchResponse, citation_from_url, push_citation,\n};\n\npub(super) fn build_body(request: &ProviderNativeSearchRequest, base_url: &str) -> Result<Value> {\n    let normalized = base_url.trim().trim_end_matches('/').to_ascii_lowercase();\n    let search_engine = match normalized.as_str() {\n        \"https://api.z.ai/api/paas/v4\" => \"search-prime\",\n        \"https://open.bigmodel.cn/api/paas/v4\" => \"search_std\",\n        _ => bail!(\"unsupported Z.AI web-search endpoint: {base_url}\"),\n    };\n    Ok(json!({\n        \"search_engine\": search_engine,\n        \"search_query\": request.query,\n        \"count\": request.max_results,\n    }))\n}\n\npub(super) fn parse(payload: &Value) -> ProviderNativeSearchResponse {\n    let mut citations = Vec::new();\n    if let Some(results) = payload.get(\"search_result\").and_then(Value::as_array) {\n        for result in results {\n            let Some(url) = result.get(\"link\").and_then(Value::as_str) else {\n                continue;\n            };\n            let title = result\n                .get(\"title\")\n                .and_then(Value::as_str)","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/client/provider_native_search/zai.rs#L1-L33","documentation":"The Z.AI web-search adapter maps the configured base URL to the upstream search_engine parameter: api.z.ai maps to \"search-prime\" and open.bigmodel.cn maps to \"search_std\". Any other (or unrecognized) base URL has no known engine mapping, so build_body refuses the request instead of guessing an engine.","triggerScenarios":"build_body receives a base_url that, after trimming trailing slashes and lowercasing, matches neither \"https://api.z.ai/api/paas/v4\" nor \"https://open.bigmodel.cn/api/paas/v4\" — e.g. a custom proxy URL or a regional endpoint.","commonSituations":"Pointing the Z.AI provider at a self-hosted proxy or gateway URL; typo in the base URL; using a new Z.AI regional endpoint not yet in the mapping; trailing path differences like /api/paas/v4/ vs configured variants.","solutions":["Set the provider base URL to exactly https://api.z.ai/api/paas/v4 or https://open.bigmodel.cn/api/paas/v4","If using a proxy, add its normalized URL to the match arms in build_body with the correct search_engine","Fix typos/extra path segments in the configured base URL","Extend the mapping if Z.AI added a new official endpoint"],"exampleFix":"// before\n_ => bail!(\"unsupported Z.AI web-search endpoint: {base_url}\"),\n// after: also accept a self-hosted proxy mapped to the standard engine\n\"https://zai-proxy.internal.example/api/paas/v4\" => \"search-prime\",\n_ => bail!(\"unsupported Z.AI web-search endpoint: {base_url}\"),","handlingStrategy":"validation","validationCode":"const SUPPORTED: [&str; 2] = [\"https://api.z.ai/api/paas/v4\", \"https://open.bigmodel.cn/api/paas/v4\"];\nassert!(SUPPORTED.contains(&base_url.trim_end_matches('/').to_ascii_lowercase().as_str()),\n        \"unsupported Z.AI endpoint: {base_url}\");","typeGuard":null,"tryCatchPattern":"match build_body(&req, base_url) {\n    Err(e) if e.to_string().contains(\"unsupported Z.AI web-search endpoint\") => {\n        eprintln!(\"{e}; defaulting to https://api.z.ai/api/paas/v4\");\n        build_body(&req, \"https://api.z.ai/api/paas/v4\")\n    }\n    other => other,\n}","preventionTips":["Copy base URLs exactly from provider docs, no trailing extras","Normalize (lowercase, strip trailing '/') before storing config","Add new official endpoints to the mapping before deploying them"],"tags":["zai","web-search","configuration","unsupported-endpoint"],"backgroundTag":"invalid-config-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}