Skip to content

fix(anthropic): surface mid-stream errors on the sync /v1/messages adapter - #43703

Open
revanth-045 wants to merge 1 commit into
BerriAI:mainfrom
revanth-045:fix/anthropic-sync-sse-mid-stream-error
Open

revanth-045 wants to merge 1 commit into
BerriAI:mainfrom
revanth-045:fix/anthropic-sync-sse-mid-stream-error

Conversation

@revanth-045

Copy link
Copy Markdown

Problem

AnthropicStreamWrapper has two SSE wrappers, and only the async one handles a mid-stream provider failure:

def anthropic_sse_wrapper(self) -> Iterator[bytes]:
    for chunk in self:            # no error handling
        ...

async def async_anthropic_sse_wrapper(self) -> AsyncIterator[bytes]:
    try:
        async for chunk in self:
            ...
    except Exception as e:
        yield _mid_stream_error_sse_event(e)

transformation.py returns the sync one whenever is_async is False, so it is a live path.

The sync case is actually worse than the pre-#43601 async behaviour. __next__ ends with:

except Exception as e:
    verbose_logger.error("Anthropic Adapter - %s\n%s", e, traceback.format_exc())
    raise StopIteration

So an upstream failure (the BedrockError on a ConverseStream that ends without a terminal messageStop, per the existing regression tests) is swallowed and converted into a clean end-of-stream. The client sees a silently truncated answer and no error event — not even the "Connection closed mid-response" that the async fix was written for. __anext__ has no such catch, which is why the async guard works.

Fix

Two lines, mirroring the async path:

  • __next__ propagates the exception instead of converting it to StopIteration (the log line stays).
  • anthropic_sse_wrapper gets the same try/except as async_anthropic_sse_wrapper, emitting _mid_stream_error_sse_event(e).

On the __next__ change: AnthropicStreamWrapper is constructed in exactly one place (transformation.py:333) and is only ever consumed through one of the two SSE wrappers, so the propagated exception is caught immediately by the guard added here and never reaches a caller that previously saw a clean stop.

Tests

Two cases added to the existing test_streaming_iterator_mid_stream_error.py, as sync mirrors of the async ones already there: a BedrockError after partial content ends the stream with a terminal Anthropic error event carrying the upstream message, and draining the wrapper does not re-raise. Both fail on main.

tests/unit/llms/anthropic/pass_through/adapters 371 passed; ruff check and ruff format --check clean on the source file. (The UP035/UP045 findings in that test file are pre-existing on main and untouched.)

🤖 Generated with Claude Code

…apter

BerriAI#43601 taught the async adapter to convert a mid-stream provider failure
into a terminal Anthropic `error` event instead of dropping the socket. The
sync path, returned by `transformation.py` whenever `is_async` is False,
never got the same treatment and was worse off: `__next__` caught every
exception and raised `StopIteration`, so the SSE stream simply ended as
though the response had completed. The client got a silently truncated
answer with no error at all.

Let `__next__` propagate, as `__anext__` already does, and give
`anthropic_sse_wrapper` the same guard as `async_anthropic_sse_wrapper` so
the failure is emitted as an Anthropic `error` event.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@revanth-045
revanth-045 requested a review from a team September 29, 2026 10:24
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


revanth-045 seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Fixes error handling in streaming response adapter.

The PR appears safe to merge; no actionable regression was identified.

Summary

The PR makes the synchronous Anthropic Messages SSE adapter report upstream mid-stream failures instead of silently ending a truncated response.

  • Re-raises failures from the sync iterator and converts them to terminal Anthropic error events at the SSE boundary.
  • Adds sync regression tests for an error after partial content and an error before upstream content.

Reviews (1) · Last reviewed commit: "fix(anthropic): surface mid-stream error..."

@codspeed

codspeed Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing revanth-045:fix/anthropic-sync-sse-mid-stream-error (3de13bc) with main (7f95b5f)

Open in CodSpeed

@codecov

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.90909% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...hropic/pass_through/adapters/streaming_iterator.py 90.90% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
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.

2 participants