{"record":{"id":"83155b6fb0e38864","repo":"nikivdev/code","slug":"gemini-api-error","errorCode":null,"errorMessage":"Gemini API error {}: {}","messagePattern":"Gemini API error (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ai.rs","lineNumber":14628,"sourceCode":"            }\n        ],\n        \"generationConfig\": {\n            \"temperature\": 0.2,\n            \"maxOutputTokens\": 700,\n            \"responseMimeType\": \"application/json\"\n        }\n    });\n\n    let resp = client\n        .post(&url)\n        .json(&payload)\n        .send()\n        .context(\"failed to call Gemini API\")?;\n\n    if !resp.status().is_success() {\n        let status = resp.status();\n        let text = resp.text().unwrap_or_default();\n        bail!(\"Gemini API error {}: {}\", status, text);\n    }\n\n    let parsed: GeminiResponse = resp.json().context(\"failed to parse Gemini response\")?;\n    let content = parsed\n        .candidates\n        .get(0)\n        .and_then(|c| c.content.parts.get(0))\n        .and_then(|p| p.text.as_deref())\n        .unwrap_or(\"\")\n        .trim();\n\n    if content.is_empty() {\n        bail!(\"Gemini returned empty summary\");\n    }\n\n    let summary_payload = parse_summary_response(content)?;\n\n    Ok(SessionSummary {","sourceCodeStart":14610,"sourceCodeEnd":14646,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ai.rs#L14610-L14646","documentation":"After sending a request to the Gemini generateContent API via reqwest, the code checks `resp.status().is_success()`. On any non-2xx response it bails with the HTTP status and the raw response body text. This surfaces server-side rejections: invalid keys, quota limits, malformed requests, or model availability problems.","triggerScenarios":"Calling the Gemini summarize API with an invalid/expired/revoked API key (401/403); exceeding quota or rate limits (429); a request body that fails validation (400); requesting a model name that doesn't exist or isn't enabled for the key (404); transient Google-side 5xx errors.","commonSituations":"Key created without Generative Language API enabled; key restricted to different APIs/referrers; large prompts exceeding token limits; shared key hitting project quota during team use; network proxies injecting error pages.","solutions":["Read the status and body in the message: 400 → fix request payload; 401/403 → fix/rotate API key and enable the Generative Language API for the project; 429 → back off and retry after quota window; 5xx → retry with backoff","Verify the key with curl against `https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY`","Check quota/limits in Google AI Studio / Cloud Console and enable billing if needed","Confirm the model name matches an available Gemini model and trim oversized context before sending"],"exampleFix":"// before\n$ myapp ai summarize gemini\nError: Gemini API error 429 Too Many Requests: {\"error\":{\"code\":429,...RESOURCE_EXHAUSTED...}}\n// after\n$ sleep 60 && myapp ai summarize gemini   # after quota window; or rotate key for 401/403","handlingStrategy":"retry","validationCode":"fn preflight_gemini(key: &str) -> Result<(), String> {\n    let url = format!(\"https://generativelanguage.googleapis.com/v1beta/models?key={key}\");\n    match reqwest::blocking::get(&url) {\n        Ok(r) if r.status().is_success() => Ok(()),\n        Ok(r) => Err(format!(\"preflight failed: {}\", r.status())),\n        Err(e) => Err(format!(\"network error: {e}\")),\n    }\n}\npreflight_gemini(&key)?;","typeGuard":null,"tryCatchPattern":"match summarize_with_gemini(ctx) {\n    Err(e) if e.to_string().starts_with(\"Gemini API error 429\") => {\n        std::thread::sleep(Duration::from_secs(60));\n        retry_with_backoff(3, || summarize_with_gemini(ctx))?;\n    }\n    Err(e) if e.to_string().starts_with(\"Gemini API error 5\") => {\n        retry_with_backoff(3, || summarize_with_gemini(ctx))?;\n    }\n    Err(e) if e.to_string().starts_with(\"Gemini API error 40\") => {\n        eprintln!(\"{e}; check API key and enabled APIs in Google AI Studio\");\n    }\n    other => other?,\n}","preventionTips":["Preflight the key with a cheap models-list call before sending large requests","Differentiate status classes: 401/403 fix credentials, 429 back off, 5xx retry; trim context to avoid 400/413","Monitor quota in Google AI Studio / Cloud Console and stagger team usage of a shared key","Pin/verify the model name and enable the Generative Language API for the key's project"],"tags":["http-error","gemini","api","network","rate-limit"],"backgroundTag":"http-api-error","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}