diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index ee179b582cf..4a25eb218c0 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -811,6 +811,24 @@ def _map_openai_like_exception( ) +_BEDROCK_MANTLE_CONTEXT_WINDOW_PATTERN: Final = re.compile(r"prompt tokens \((\d+)\) exceed model maximum \((\d+)\)") + + +def _get_bedrock_mantle_context_window_message(error_str: str) -> str | None: + """ + Mantle reports context overflow as a structured validation error rather than + the plain-text patterns Bedrock itself uses, so it needs its own detection and a + message clients recognize as context overflow (litellm/litellm#36546). + """ + if "invalid_request_error" not in error_str and "validation_error" not in error_str: + return None + match = _BEDROCK_MANTLE_CONTEXT_WINDOW_PATTERN.search(error_str) + if match is None: + return None + prompt_tokens, max_tokens = match.groups() + return f"prompt is too long: {prompt_tokens} tokens > {max_tokens} maximum" + + def _map_bedrock_exception( *, model: str, @@ -821,6 +839,14 @@ def _map_bedrock_exception( exception_provider: str, extra_information: str, ) -> None: + if custom_llm_provider == "bedrock_mantle": + mantle_context_window_message = _get_bedrock_mantle_context_window_message(error_str) + if mantle_context_window_message is not None: + raise ContextWindowExceededError( + message=mantle_context_window_message, + model=model, + llm_provider=custom_llm_provider, + ) if ( "too many tokens" in error_str or "expected maxLength:" in error_str diff --git a/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py b/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py index 904675d4adc..38f46b26eea 100644 --- a/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py +++ b/tests/test_litellm/litellm_core_utils/test_exception_mapping_utils.py @@ -785,3 +785,27 @@ def test_bedrock_mantle_400_maps_to_bad_request(): assert excinfo.value.status_code == 400 assert "Invalid 'input'" in excinfo.value.message + assert type(excinfo.value) is litellm.BadRequestError + + +def test_bedrock_mantle_context_overflow_maps_to_context_window_exceeded(): + from litellm.llms.base_llm.chat.transformation import BaseLLMException + + original_exception = BaseLLMException( + status_code=400, + message=( + '{"error":{"code":"validation_error",' + '"message":"prompt tokens (1055489) exceed model maximum (1050000) for openai.gpt-5.6-sol",' + '"param":null,"type":"invalid_request_error"}}' + ), + ) + + with pytest.raises(litellm.ContextWindowExceededError) as excinfo: + exception_type( + model="openai.gpt-5.6-sol", + original_exception=original_exception, + custom_llm_provider="bedrock_mantle", + ) + + assert excinfo.value.status_code == 400 + assert "prompt is too long: 1055489 tokens > 1050000 maximum" in excinfo.value.message