{"record":{"id":"6f69664c66651ec9","repo":"Hmbown/CodeWhale","slug":"err-last-error","errorCode":null,"errorMessage":"err.last_error","messagePattern":"err\\.last_error","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":3506,"sourceCode":"            Err(err) => {\n                if let LlmError::RateLimited { retry_after, .. } = &err.last_error {\n                    crate::retry_status::note_rate_limit(\n                        retry_after\n                            .unwrap_or_else(|| retry_cfg.delay_for_attempt(retry_cfg.max_retries)),\n                    );\n                }\n                let last = err.last_error.to_string();\n                if err.attempts > 1 {\n                    crate::retry_status::failed(last.clone());\n                } else {\n                    crate::retry_status::clear();\n                }\n                self.mark_request_failure(&last).await;\n                self.maybe_probe_recovery().await;\n                // Keep the structured `LlmError` downcastable so failure\n                // surfaces can classify auth/rate-limit/invalid-request\n                // instead of reporting an opaque string (#3884).\n                Err(anyhow::Error::new(err.last_error))\n            }\n        }\n    }\n\n    /// The same bounded transport retry policy without process-global retry\n    /// banners, provider-wide pause cells, or shared connection-health writes.\n    /// Used only by the Auto classifier during read-only request inspection.\n    async fn send_with_isolated_retry<F>(\n        &self,\n        mut build: F,\n        include_error_body: bool,\n    ) -> Result<reqwest::Response>\n    where\n        F: FnMut() -> reqwest::RequestBuilder,\n    {\n        let retry_cfg: LlmRetryConfig = self.retry.clone().into();\n        let request_result = with_retry(\n            &retry_cfg,","sourceCodeStart":3488,"sourceCodeEnd":3524,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/client.rs#L3488-L3524","documentation":"After exhausting the bounded transport retry policy, the client rethrows the underlying error via anyhow::Error::new(err.last_error). The final error a caller sees is the last LlmError from the request loop, with its structured type preserved for downcasting so auth/rate-limit/invalid-request failures stay classifiable (#3884).","triggerScenarios":"Any LLM request that fails on every retry attempt: mark_request_failure has been called and maybe_probe_recovery has run, then the last_error is surfaced to the caller.","commonSituations":"Provider outage lasting longer than the retry window; persistent 401/403 from a revoked API key; sustained rate limiting; malformed requests rejected on every attempt.","solutions":["Downcast the anyhow error to LlmError to classify auth vs rate-limit vs network before deciding on user messaging","Check the provider status / API key validity indicated by the underlying LlmError variant","If transient, wait for the recovery probe to restore the connection and retry"],"exampleFix":"// before\nif let Err(e) = client.send(req).await { log::error!(\"{}\", e); }\n// after\nif let Err(e) = client.send(req).await {\n    if let Some(llm) = e.downcast_ref::<LlmError>() {\n        match llm { LlmError::Auth(_) => reauth(), LlmError::RateLimit(_) => backoff(), _ => {} }\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn classify(e: &anyhow::Error) -> Option<&LlmError> { e.downcast_ref::<LlmError>() }","tryCatchPattern":"match client.send(req).await {\n    Err(e) => match e.downcast_ref::<LlmError>() {\n        Some(LlmError::Auth(_)) => reauthenticate(),\n        Some(LlmError::RateLimit(_)) => schedule_backoff(),\n        _ => report_transport_failure(&e),\n    },\n    ok => ok,\n}","preventionTips":["Always downcast to LlmError instead of string-matching messages","Monitor provider status pages and key validity for recurring failures","Keep retry budgets sized to transient-only failures"],"tags":["rust","llm","retry","network"],"backgroundTag":"api-request-failed","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}