{"record":{"id":"b55ff3e1c79d3da8","repo":"tonhowtf/omniget","slug":"http-ai-keys","errorCode":null,"errorMessage":"HTTP {}: {}","messagePattern":"HTTP (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/ai_keys.rs","lineNumber":356,"sourceCode":"                entry.base_url, entry.key\n            ))\n            .send()\n            .await?\n            .error_for_status()\n            .map_err(|e| anyhow!(\"Gemini: {}\", e))?\n            .json()\n            .await?\n        }\n        _ => {\n            let mut req = c.get(format!(\"{}/models\", entry.base_url));\n            if !entry.key.is_empty() {\n                req = req.bearer_auth(&entry.key);\n            }\n            let resp = req.send().await?;\n            let status = resp.status();\n            let text = resp.text().await.unwrap_or_default();\n            if !status.is_success() {\n                return Err(anyhow!(\n                    \"HTTP {}: {}\",\n                    status.as_u16(),\n                    text.chars().take(200).collect::<String>()\n                ));\n            }\n            serde_json::from_str(&text).map_err(|_| {\n                anyhow!(\n                    \"resposta nao e JSON: {}\",\n                    text.chars().take(120).collect::<String>()\n                )\n            })?\n        }\n    };\n    let arr = json\n        .get(\"data\")\n        .or_else(|| json.get(\"models\"))\n        .and_then(|v| v.as_array())\n        .cloned()","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/ai_keys.rs#L338-L374","documentation":"The models() function in ai_keys.rs performs an HTTP request to a provider's model-list endpoint and throws this error when the response status is not a success (2xx). It includes the numeric status code and up to 200 chars of the response body so the developer can see the provider's own error message. It wraps any non-2xx outcome: 401/403 for bad keys, 404 for wrong base_url paths, 429 for rate limits, 5xx for provider outages.","triggerScenarios":"Calling models() for a key whose provider endpoint returns 401 (invalid/revoked API key), 404 (base_url missing /models path or wrong route), 429 (rate limited), or 5xx; also when the request goes through but the provider rejects the bearer token.","commonSituations":"Expired or rotated API keys still stored in the key manager; base_url set to the site root instead of the API base (e.g. missing /v1); provider temporarily down; free-tier rate limits hit while listing models.","solutions":["Check the status code and body in the error message: 401/403 means fix or re-enter the API key via the key manager; 404 means fix base_url to point at the API root (usually includes /v1).","Re-test the key directly with curl against the provider's /models endpoint to confirm credentials and URL work outside the app.","Handle 429 by waiting and retrying with backoff; 5xx is a provider-side outage, retry later.","If the provider changed its API routes, update the base_url stored for the key entry."],"exampleFix":"// before\nlet base = \"https://api.openai.com\"; // missing /v1 -> 404\n// after\nlet base = \"https://api.openai.com/v1\";","handlingStrategy":"try-catch","validationCode":"// pre-check the endpoint before calling models()\nlet resp = reqwest::Client::new()\n    .get(format!(\"{base_url}/models\"))\n    .bearer_auth(&key)\n    .send().await?;\nif !resp.status().is_success() {\n    eprintln!(\"provider returned {} — fix key/base_url first\", resp.status());\n}","typeGuard":"fn is_ok_status(status: u16) -> bool { (200..300).contains(&status) }","tryCatchPattern":"match models(id).await {\n    Ok(list) => use(list),\n    Err(e) if e.to_string().starts_with(\"HTTP 401\") || e.to_string().starts_with(\"HTTP 403\") => prompt_reenter_key(),\n    Err(e) if e.to_string().starts_with(\"HTTP 429\") => retry_with_backoff(),\n    Err(e) => show_error(e),\n}","preventionTips":["Rotate and re-test API keys regularly","Store the full API base (including /v1), not the site root","Handle 429 with exponential backoff","Watch provider status pages for 5xx outages"],"tags":["http","api","network"],"backgroundTag":"http-error-response","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}