From d0d221c68ba675d388b4a89f0696717ab7e19b45 Mon Sep 17 00:00:00 2001 From: Rachit Mehta Date: Mon, 27 Oct 2025 10:30:00 -0400 Subject: [PATCH] fix (bug): retry on varying Bedrock throttlingexception cases --- src/strands/models/bedrock.py | 5 +++- tests/strands/models/test_bedrock.py | 34 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/strands/models/bedrock.py b/src/strands/models/bedrock.py index 43a3a3ed4..576f7c43e 100644 --- a/src/strands/models/bedrock.py +++ b/src/strands/models/bedrock.py @@ -715,7 +715,10 @@ def _stream( except ClientError as e: error_message = str(e) - if e.response["Error"]["Code"] == "ThrottlingException": + if ( + e.response["Error"]["Code"] == "ThrottlingException" + or e.response["Error"]["Code"] == "throttlingException" + ): raise ModelThrottledException(error_message) from e if any(overflow_message in error_message for overflow_message in BEDROCK_CONTEXT_WINDOW_OVERFLOW_MESSAGES): diff --git a/tests/strands/models/test_bedrock.py b/tests/strands/models/test_bedrock.py index f6251943d..4a6a0f9b0 100644 --- a/tests/strands/models/test_bedrock.py +++ b/tests/strands/models/test_bedrock.py @@ -535,6 +535,40 @@ async def test_stream_throttling_exception_from_general_exception(bedrock_client ) +@pytest.mark.asyncio +async def test_stream_throttling_exception_lowercase(bedrock_client, model, messages, alist): + """Test that lowercase throttlingException is converted to ModelThrottledException.""" + error_message = "throttlingException: Rate exceeded for ConverseStream" + bedrock_client.converse_stream.side_effect = ClientError( + {"Error": {"Message": error_message, "Code": "throttlingException"}}, "Any" + ) + + with pytest.raises(ModelThrottledException) as excinfo: + await alist(model.stream(messages)) + + assert error_message in str(excinfo.value) + bedrock_client.converse_stream.assert_called_once_with( + modelId="m1", messages=messages, system=[], inferenceConfig={} + ) + + +@pytest.mark.asyncio +async def test_stream_throttling_exception_lowercase_non_streaming(bedrock_client, messages, alist): + """Test that lowercase throttlingException is converted to ModelThrottledException in non-streaming mode.""" + error_message = "throttlingException: Rate exceeded for Converse" + bedrock_client.converse.side_effect = ClientError( + {"Error": {"Message": error_message, "Code": "throttlingException"}}, "Any" + ) + + model = BedrockModel(model_id="test-model", streaming=False) + with pytest.raises(ModelThrottledException) as excinfo: + await alist(model.stream(messages)) + + assert error_message in str(excinfo.value) + bedrock_client.converse.assert_called_once() + bedrock_client.converse_stream.assert_not_called() + + @pytest.mark.asyncio async def test_general_exception_is_raised(bedrock_client, model, messages, alist): error_message = "Should be raised up"