From 411bb639905e8f457bcdb6b6ced0f2533ab5b638 Mon Sep 17 00:00:00 2001 From: Kian Jones <11655409+kianjones9@users.noreply.github.com> Date: Wed, 11 Feb 2026 10:53:28 -0800 Subject: [PATCH] fix(core): improve error handling for upstream LLM provider errors (#9423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle HTML error responses from ALB/load balancers in OpenAI client and add explicit InternalServerError handling for Anthropic upstream issues. 🐛 Generated with [Letta Code](https://letta.com) Co-authored-by: Letta --- letta/llm_api/anthropic_client.py | 28 +++++++++++++++++++++++++++- letta/llm_api/openai_client.py | 18 ++++++++++++------ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/letta/llm_api/anthropic_client.py b/letta/llm_api/anthropic_client.py index 442aceea..c84004a6 100644 --- a/letta/llm_api/anthropic_client.py +++ b/letta/llm_api/anthropic_client.py @@ -1059,9 +1059,35 @@ class AnthropicClient(LLMClientBase): details={"is_byok": is_byok}, ) + if isinstance(e, anthropic.InternalServerError): + error_str = str(e).lower() + if "overflow" in error_str or "upstream connect error" in error_str: + logger.warning(f"[Anthropic] Upstream infrastructure error (transient): {str(e)}") + return LLMServerError( + message=f"Anthropic upstream infrastructure error (transient, may resolve on retry): {str(e)}", + code=ErrorCode.INTERNAL_SERVER_ERROR, + details={ + "status_code": e.status_code if hasattr(e, "status_code") else None, + "transient": True, + }, + ) + if "overloaded" in error_str: + return LLMProviderOverloaded( + message=f"Anthropic API is overloaded: {str(e)}", + code=ErrorCode.INTERNAL_SERVER_ERROR, + ) + logger.warning(f"[Anthropic] Internal server error: {str(e)}") + return LLMServerError( + message=f"Anthropic internal server error: {str(e)}", + code=ErrorCode.INTERNAL_SERVER_ERROR, + details={ + "status_code": e.status_code if hasattr(e, "status_code") else None, + "response": str(e.response) if hasattr(e, "response") else None, + }, + ) + if isinstance(e, anthropic.APIStatusError): logger.warning(f"[Anthropic] API status error: {str(e)}") - # Handle 413 Request Entity Too Large - request payload exceeds size limits if hasattr(e, "status_code") and e.status_code == 413: logger.warning(f"[Anthropic] Request too large (413): {str(e)}") return ContextWindowExceededError( diff --git a/letta/llm_api/openai_client.py b/letta/llm_api/openai_client.py index 7b6f84e2..b48280cb 100644 --- a/letta/llm_api/openai_client.py +++ b/letta/llm_api/openai_client.py @@ -1074,24 +1074,30 @@ class OpenAIClient(LLMClientBase): if isinstance(e, openai.BadRequestError): logger.warning(f"[OpenAI] Bad request (400): {str(e)}") - # BadRequestError can signify different issues (e.g., invalid args, context length) - # Check for context_length_exceeded error code in the error body + error_str = str(e) + + if "