diff --git a/litellm/llms/openrouter/chat/transformation.py b/litellm/llms/openrouter/chat/transformation.py index e3770dbbf49..05d03ce248a 100644 --- a/litellm/llms/openrouter/chat/transformation.py +++ b/litellm/llms/openrouter/chat/transformation.py @@ -211,6 +211,30 @@ class OpenrouterConfig(OpenAIGPTConfig): json_mode=json_mode, ) + # Check for error embedded in response body (OpenRouter-specific behavior) + # OpenRouter can return errors in a 200 response when a downstream provider fails + try: + response_json = raw_response.json() + if "error" in response_json: + error_chunk = response_json["error"] + error_msg = OpenRouterErrorMessage( + message="Message: {}, Metadata: {}".format( + error_chunk.get("message", "Unknown error"), + error_chunk.get("metadata", {}), + ), + code=error_chunk.get("code", 500), + metadata=error_chunk.get("metadata", {}), + ) + raise OpenRouterException( + message=error_msg["message"], + status_code=error_msg["code"], + headers=error_msg["metadata"].get("headers", {}), + ) + except OpenRouterException: + raise + except Exception: + pass + # Extract cost from OpenRouter response body # OpenRouter returns cost information in the usage object when usage.include=true try: diff --git a/ruff.toml b/ruff.toml index a3104466710..43ff802a684 100644 --- a/ruff.toml +++ b/ruff.toml @@ -12,4 +12,7 @@ exclude = ["litellm/types/*", "litellm/__init__.py", "litellm/proxy/example_conf "litellm/llms/anthropic/chat/__init__.py" = ["F401"] "litellm/llms/azure_ai/embed/__init__.py" = ["F401"] "litellm/llms/azure_ai/rerank/__init__.py" = ["F401"] -"litellm/llms/bedrock/chat/__init__.py" = ["F401"] \ No newline at end of file +"litellm/llms/bedrock/chat/__init__.py" = ["F401"] +"litellm/proxy/utils.py" = ["F401", "PLR0915"] +"litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py" = ["PLR0915"] +"litellm/proxy/guardrails/guardrail_hooks/guardrail_benchmarks/test_eval.py" = ["PLR0915"]