Skip to content

fix: handle error SSE events from Bedrock without AttributeError#1572

Open
pintaste wants to merge 1 commit into
anthropics:mainfrom
pintaste:fix/streaming-null-safety
Open

fix: handle error SSE events from Bedrock without AttributeError#1572
pintaste wants to merge 1 commit into
anthropics:mainfrom
pintaste:fix/streaming-null-safety

Conversation

@pintaste
Copy link
Copy Markdown

Problem

Bedrock delivers all event-stream frames over HTTP 200, including error payloads (rate-limit, model-not-found, etc.). AWSEventStreamDecoder previously emitted every decoded frame as ServerSentEvent(event=\"completion\"), so a Bedrock error payload such as:

{"type": "error", "error": {"type": "rate_limit_error", "message": "Rate limited", "details": null}, "request_id": "req_..."}

was routed to _process_response_data and cast to the stream event union type. The cast produced a RawMessageStartEvent whose required message field was None, causing:

AttributeError: 'NoneType' object has no attribute 'model'
AttributeError: 'NoneType' object has no attribute 'usage'

This was intermittently reproducible with global.anthropic.claude-opus-4-7 cross-region inference profiles on Bedrock.

Fix

Add _sse_event_type() to AWSEventStreamDecoder which inspects the decoded JSON and returns "error" when type == "error". The existing Stream.__stream__ / AsyncStream.__stream__ methods in _streaming.py already contain a handler for sse.event == \"error\" that raises _make_status_error, so this routes the payload through the correct path and surfaces a clean APIStatusError instead of an AttributeError.

No changes to the streaming core are required; the fix is entirely contained in src/anthropic/lib/bedrock/_stream_decoder.py.

Fixes #1472

Bedrock delivers all event-stream frames over HTTP 200, including error
payloads such as rate-limit or model-not-found responses.  Previously,
`AWSEventStreamDecoder` emitted every decoded frame as
`ServerSentEvent(event="completion")`, so a payload like

    {"type": "error", "error": {"type": "rate_limit_error", ...}}

was passed to `_process_response_data` and cast to the stream event
union type.  The cast produced a `RawMessageStartEvent` whose required
`message` field was `None`, causing downstream code to raise
`AttributeError: 'NoneType' object has no attribute 'model'` (or
`'usage'`, etc.) instead of a clean `APIStatusError`.

Fix: add `_sse_event_type()` which peeks at the decoded JSON and returns
`"error"` when `type == "error"`.  The `Stream.__stream__` /
`AsyncStream.__stream__` methods in `_streaming.py` already contain a
handler for `sse.event == "error"` that raises `_make_status_error`, so
this routes the payload through the correct path without any additional
changes to the streaming core.

Fixes anthropics#1472
@pintaste pintaste requested a review from a team as a code owner May 19, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming error SSE event causes AttributeError: 'NoneType' object has no attribute errors

1 participant