mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-15 00:22:34 +00:00
fix(gemini): properly catch context window exceeded errors
Fixes #18282 This PR fixes two issues with Gemini context window error handling: 1. **Pattern matching for Gemini 2.0 Flash**: The previous pattern 'input token count exceeds the maximum number of tokens allowed' doesn't match Gemini 2.0 Flash errors which include dynamic token counts like '(2800010)' in the message. Split into shorter patterns that work with both formats. 2. **Add context window check to Gemini block**: The is_error_str_context_window_exceeded() check was only called for OpenAI-compatible providers, not for Gemini/Vertex AI. Added the check to the Gemini-specific error handling block. Test cases added for both Gemini 2.0 Flash and 2.5/3 error formats.
This commit is contained in:
@@ -78,9 +78,7 @@ class ExceptionCheckers:
|
||||
"is longer than the model's context length",
|
||||
"input tokens exceed the configured limit",
|
||||
"`inputs` tokens + `max_new_tokens` must be",
|
||||
# Gemini pattern: "The input token count exceeds the maximum number of tokens allowed"
|
||||
# See: https://github.com/BerriAI/litellm/issues/XXXX
|
||||
"input token count exceeds the maximum number of tokens allowed",
|
||||
"exceeds the maximum number of tokens allowed", # Gemini
|
||||
]
|
||||
for substring in known_exception_substrings:
|
||||
if substring in _error_str_lowercase:
|
||||
@@ -1262,6 +1260,14 @@ def exception_type( # type: ignore # noqa: PLR0915
|
||||
model=model,
|
||||
llm_provider=custom_llm_provider,
|
||||
)
|
||||
elif ExceptionCheckers.is_error_str_context_window_exceeded(error_str):
|
||||
exception_mapping_worked = True
|
||||
raise ContextWindowExceededError(
|
||||
message=f"ContextWindowExceededError: {custom_llm_provider.capitalize()}Exception - {error_str}",
|
||||
model=model,
|
||||
llm_provider=custom_llm_provider,
|
||||
litellm_debug_info=extra_information,
|
||||
)
|
||||
elif (
|
||||
"None Unknown Error." in error_str
|
||||
or "Content has no parts." in error_str
|
||||
|
||||
@@ -40,8 +40,7 @@ context_window_test_cases = [
|
||||
"`inputs` tokens + `max_new_tokens` must be <= 4096",
|
||||
True,
|
||||
),
|
||||
# Gemini context window error format
|
||||
# See: https://github.com/BerriAI/litellm/issues/XXXX
|
||||
# Gemini 2.5/3 format
|
||||
(
|
||||
"The input token count exceeds the maximum number of tokens allowed 1048576.",
|
||||
True,
|
||||
@@ -50,6 +49,15 @@ context_window_test_cases = [
|
||||
"GeminiException BadRequestError - {\n \"error\": {\n \"code\": 400,\n \"message\": \"The input token count exceeds the maximum number of tokens allowed 1048576.\",\n \"status\": \"INVALID_ARGUMENT\"\n }\n}\n",
|
||||
True,
|
||||
),
|
||||
# Gemini 2.0 Flash format (includes input token count in message)
|
||||
(
|
||||
"The input token count (2800010) exceeds the maximum number of tokens allowed (1048575).",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"GeminiException BadRequestError - {\n \"error\": {\n \"code\": 400,\n \"message\": \"The input token count (2800010) exceeds the maximum number of tokens allowed (1048575).\",\n \"status\": \"INVALID_ARGUMENT\"\n }\n}\n",
|
||||
True,
|
||||
),
|
||||
# Test case insensitivity
|
||||
("ERROR: THIS MODEL'S MAXIMUM CONTEXT LENGTH IS 1024.", True),
|
||||
# Cerebras context window error format
|
||||
@@ -169,6 +177,54 @@ class TestExceptionCheckers:
|
||||
result = ExceptionCheckers.is_azure_content_policy_violation_error(error_str)
|
||||
assert result is False, f"Should NOT detect policy violation in: {error_str}"
|
||||
|
||||
gemini_context_window_test_cases = [
|
||||
# Gemini 2.0 Flash format (includes input token count in message)
|
||||
(
|
||||
"The input token count (2800010) exceeds the maximum number of tokens allowed (1048575).",
|
||||
True,
|
||||
),
|
||||
# Gemini 2.5/3 format
|
||||
(
|
||||
"The input token count exceeds the maximum number of tokens allowed (1048576).",
|
||||
True,
|
||||
),
|
||||
("A generic error occurred.", False),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"error_message, should_raise_context_window", gemini_context_window_test_cases
|
||||
)
|
||||
def test_gemini_context_window_error_mapping(error_message, should_raise_context_window):
|
||||
"""
|
||||
Tests that the exception_type function correctly maps Gemini's
|
||||
context window exceeded errors to litellm.ContextWindowExceededError.
|
||||
"""
|
||||
model = "gemini/gemini-2.0-flash"
|
||||
custom_llm_provider = "gemini"
|
||||
|
||||
# Create a generic exception with the specific error message
|
||||
original_exception = Exception(error_message)
|
||||
|
||||
if should_raise_context_window:
|
||||
with pytest.raises(litellm.ContextWindowExceededError) as excinfo:
|
||||
exception_type(
|
||||
model=model,
|
||||
original_exception=original_exception,
|
||||
custom_llm_provider=custom_llm_provider,
|
||||
)
|
||||
# Check if the raised exception is indeed a ContextWindowExceededError
|
||||
assert isinstance(excinfo.value, litellm.ContextWindowExceededError)
|
||||
else:
|
||||
# For the negative case, we expect it to raise a generic APIConnectionError
|
||||
with pytest.raises(litellm.APIConnectionError):
|
||||
exception_type(
|
||||
model=model,
|
||||
original_exception=original_exception,
|
||||
custom_llm_provider=custom_llm_provider,
|
||||
)
|
||||
|
||||
|
||||
# Test cases for Vertex AI RateLimitError mapping
|
||||
# As per https://github.com/BerriAI/litellm/issues/16189
|
||||
vertex_rate_limit_test_cases = [
|
||||
|
||||
Reference in New Issue
Block a user