Skip to content

fix: handle missing usage metadata on premature Anthropic stream termination#1898

Open
giulio-leone wants to merge 1 commit intostrands-agents:mainfrom
giulio-leone:fix/anthropic-stream-usage-crash
Open

fix: handle missing usage metadata on premature Anthropic stream termination#1898
giulio-leone wants to merge 1 commit intostrands-agents:mainfrom
giulio-leone:fix/anthropic-stream-usage-crash

Conversation

@giulio-leone
Copy link
Contributor

Problem

When the Anthropic API stream terminates before sending the message_stop event (e.g., network timeout, connection reset, server error mid-stream), AnthropicModel.stream() crashes with AttributeError.

Crash site (line 412):

usage = event.message.usage  # type: ignore
yield self.format_chunk({"type": "metadata", "usage": usage.model_dump()})

Two failure modes:

  1. Empty stream: The event variable is never assigned by the async for loop → UnboundLocalError
  2. Premature termination: The last event lacks a .message attribute or .message.usage is NoneAttributeError: 'NoneType' object has no attribute 'model_dump'

Root Cause

The code unconditionally accesses event.message.usage after the async iteration loop, assuming the Anthropic stream always completes normally with usage metadata. This assumption fails when:

  • Network connection drops mid-stream
  • Server times out before message_stop
  • API returns an error partway through streaming

Fix

  1. Initialize event = None before the loop
  2. Use safe attribute access via getattr() chain: getattr(getattr(event, "message", None), "usage", None)
  3. When usage data is unavailable, emit zero-usage metadata and log a warning instead of crashing

The agent can still process whatever partial response was received before the stream terminated.

Tests

Added two regression tests:

  • test_stream_premature_termination: Stream ends with an event that has no .message attribute
  • test_stream_empty_no_events: Completely empty stream (zero events)

All 43 existing tests continue to pass.

Fixes #1868

…ination

When the Anthropic API stream terminates before sending the
message_stop event (e.g. network timeout, connection reset), the code
crashes with AttributeError because event.message.usage is None.

The stream() method unconditionally accessed event.message.usage after
the async iteration loop, assuming a complete stream. Two failure modes:
1. Empty stream: 'event' variable is never assigned (UnboundLocalError)
2. Premature termination: event.message or event.message.usage is None

Fix: Initialize event=None before the loop, use safe attribute access
via getattr() chain, and emit zero-usage metadata with a warning log
when usage data is unavailable.

Added two regression tests:
- test_stream_premature_termination: stream ends without message.usage
- test_stream_empty_no_events: completely empty stream

Fixes strands-agents#1868
@giulio-leone giulio-leone force-pushed the fix/anthropic-stream-usage-crash branch from 732a8d6 to ba341eb Compare March 15, 2026 16:12
@github-actions github-actions bot added size/s and removed size/s labels Mar 15, 2026
@giulio-leone
Copy link
Contributor Author

Friendly ping — handles missing usage metadata on premature Anthropic stream termination, preventing AttributeError crashes when the stream is interrupted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] AttributeError on event.message.usage when Anthropic stream terminates before message_stop

1 participant