From 61a4cd0c1e3a24f5a1a421f369d7d7d242edc7ef Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 27 Feb 2026 10:59:15 +0100 Subject: [PATCH 1/5] ref(anthropic): Skip accumulation logic for unexpected types in streamed response --- sentry_sdk/integrations/anthropic.py | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index ada57aebd7..1db8de446d 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -38,6 +38,16 @@ Omit = None from anthropic.resources import AsyncMessages, Messages + from anthropic.types import RawMessageStreamEvent + + from anthropic.types import ( + RawMessageStartEvent, + RawMessageDeltaEvent, + RawMessageStopEvent, + RawContentBlockStartEvent, + RawContentBlockDeltaEvent, + RawContentBlockStopEvent, + ) if TYPE_CHECKING: from anthropic.types import MessageStreamEvent, TextBlockParam @@ -406,6 +416,20 @@ def new_iterator() -> "Iterator[MessageStreamEvent]": content_blocks: "list[str]" = [] for event in old_iterator: + if not isinstance( + event, + ( + RawMessageStartEvent, + RawMessageDeltaEvent, + RawMessageStopEvent, + RawContentBlockStartEvent, + RawContentBlockDeltaEvent, + RawContentBlockStopEvent, + ), + ): + yield event + continue + ( model, usage, @@ -444,6 +468,20 @@ async def new_iterator_async() -> "AsyncIterator[MessageStreamEvent]": content_blocks: "list[str]" = [] async for event in old_iterator: + if not isinstance( + event, + ( + RawMessageStartEvent, + RawMessageDeltaEvent, + RawMessageStopEvent, + RawContentBlockStartEvent, + RawContentBlockDeltaEvent, + RawContentBlockStopEvent, + ), + ): + yield event + continue + ( model, usage, From d47b64dc29e09f59ca63de2d2423e2359502c64b Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 27 Feb 2026 14:03:49 +0100 Subject: [PATCH 2/5] . --- sentry_sdk/integrations/anthropic.py | 80 +++++++++++++++++++++------- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index 8fb2e835d1..f8de17536e 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -40,13 +40,27 @@ from anthropic.resources import AsyncMessages, Messages from anthropic.types import RawMessageStreamEvent + message_types_have_raw_prefix = False + try: + # http://github.com/anthropics/anthropic-sdk-python/commit/bc9d11cd2addec6976c46db10b7c89a8c276101a + from anthropic.types import ( + RawMessageStartEvent, + RawMessageDeltaEvent, + RawMessageStopEvent, + RawContentBlockStartEvent, + RawContentBlockDeltaEvent, + RawContentBlockStopEvent, + ) + except ImportError: + message_types_have_raw_prefix = True + from anthropic.types import ( - RawMessageStartEvent, - RawMessageDeltaEvent, - RawMessageStopEvent, - RawContentBlockStartEvent, - RawContentBlockDeltaEvent, - RawContentBlockStopEvent, + MessageStartEvent, + MessageDeltaEvent, + MessageStopEvent, + ContentBlockStartEvent, + ContentBlockDeltaEvent, + ContentBlockStopEvent, ) if TYPE_CHECKING: @@ -418,15 +432,28 @@ def new_iterator() -> "Iterator[MessageStreamEvent]": content_blocks: "list[str]" = [] for event in old_iterator: - if not isinstance( + if ( + message_types_have_raw_prefix + and not isinstance( + event, + ( + RawMessageStartEvent, + RawMessageDeltaEvent, + RawMessageStopEvent, + RawContentBlockStartEvent, + RawContentBlockDeltaEvent, + RawContentBlockStopEvent, + ), + ) + ) or not isinstance( event, ( - RawMessageStartEvent, - RawMessageDeltaEvent, - RawMessageStopEvent, - RawContentBlockStartEvent, - RawContentBlockDeltaEvent, - RawContentBlockStopEvent, + MessageStartEvent, + MessageDeltaEvent, + MessageStopEvent, + ContentBlockStartEvent, + ContentBlockDeltaEvent, + ContentBlockStopEvent, ), ): yield event @@ -470,15 +497,28 @@ async def new_iterator_async() -> "AsyncIterator[MessageStreamEvent]": content_blocks: "list[str]" = [] async for event in old_iterator: - if not isinstance( + if ( + message_types_have_raw_prefix + and not isinstance( + event, + ( + RawMessageStartEvent, + RawMessageDeltaEvent, + RawMessageStopEvent, + RawContentBlockStartEvent, + RawContentBlockDeltaEvent, + RawContentBlockStopEvent, + ), + ) + ) or not isinstance( event, ( - RawMessageStartEvent, - RawMessageDeltaEvent, - RawMessageStopEvent, - RawContentBlockStartEvent, - RawContentBlockDeltaEvent, - RawContentBlockStopEvent, + MessageStartEvent, + MessageDeltaEvent, + MessageStopEvent, + ContentBlockStartEvent, + ContentBlockDeltaEvent, + ContentBlockStopEvent, ), ): yield event From 384351f3ca05dc2981210d0f9d9f83dfb0c63303 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 27 Feb 2026 14:06:43 +0100 Subject: [PATCH 3/5] remove duplicate import --- sentry_sdk/integrations/anthropic.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index f8de17536e..1e08105826 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -38,7 +38,6 @@ Omit = None from anthropic.resources import AsyncMessages, Messages - from anthropic.types import RawMessageStreamEvent message_types_have_raw_prefix = False try: From 55d5c27aa54a9f3285e86489ca49e88a63dc8890 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 27 Feb 2026 14:17:04 +0100 Subject: [PATCH 4/5] . --- sentry_sdk/integrations/anthropic.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index 1e08105826..4f6bc48551 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -39,7 +39,6 @@ from anthropic.resources import AsyncMessages, Messages - message_types_have_raw_prefix = False try: # http://github.com/anthropics/anthropic-sdk-python/commit/bc9d11cd2addec6976c46db10b7c89a8c276101a from anthropic.types import ( @@ -51,7 +50,12 @@ RawContentBlockStopEvent, ) except ImportError: - message_types_have_raw_prefix = True + RawMessageStartEvent = None + RawMessageDeltaEvent = None + RawMessageStopEvent = None + RawContentBlockStartEvent = None + RawContentBlockDeltaEvent = None + RawContentBlockStopEvent = None from anthropic.types import ( MessageStartEvent, @@ -432,7 +436,7 @@ def new_iterator() -> "Iterator[MessageStreamEvent]": for event in old_iterator: if ( - message_types_have_raw_prefix + RawMessageStartEvent is not None and not isinstance( event, ( @@ -497,7 +501,7 @@ async def new_iterator_async() -> "AsyncIterator[MessageStreamEvent]": async for event in old_iterator: if ( - message_types_have_raw_prefix + RawMessageStartEvent is not None and not isinstance( event, ( From fd84837d4e335e85924aedb7108364aa66df3446 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 27 Feb 2026 14:25:36 +0100 Subject: [PATCH 5/5] simplify --- sentry_sdk/integrations/anthropic.py | 48 ++-------------------------- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/sentry_sdk/integrations/anthropic.py b/sentry_sdk/integrations/anthropic.py index 4f6bc48551..aa725b4a7b 100644 --- a/sentry_sdk/integrations/anthropic.py +++ b/sentry_sdk/integrations/anthropic.py @@ -39,24 +39,6 @@ from anthropic.resources import AsyncMessages, Messages - try: - # http://github.com/anthropics/anthropic-sdk-python/commit/bc9d11cd2addec6976c46db10b7c89a8c276101a - from anthropic.types import ( - RawMessageStartEvent, - RawMessageDeltaEvent, - RawMessageStopEvent, - RawContentBlockStartEvent, - RawContentBlockDeltaEvent, - RawContentBlockStopEvent, - ) - except ImportError: - RawMessageStartEvent = None - RawMessageDeltaEvent = None - RawMessageStopEvent = None - RawContentBlockStartEvent = None - RawContentBlockDeltaEvent = None - RawContentBlockStopEvent = None - from anthropic.types import ( MessageStartEvent, MessageDeltaEvent, @@ -435,20 +417,7 @@ def new_iterator() -> "Iterator[MessageStreamEvent]": content_blocks: "list[str]" = [] for event in old_iterator: - if ( - RawMessageStartEvent is not None - and not isinstance( - event, - ( - RawMessageStartEvent, - RawMessageDeltaEvent, - RawMessageStopEvent, - RawContentBlockStartEvent, - RawContentBlockDeltaEvent, - RawContentBlockStopEvent, - ), - ) - ) or not isinstance( + if not isinstance( event, ( MessageStartEvent, @@ -500,20 +469,7 @@ async def new_iterator_async() -> "AsyncIterator[MessageStreamEvent]": content_blocks: "list[str]" = [] async for event in old_iterator: - if ( - RawMessageStartEvent is not None - and not isinstance( - event, - ( - RawMessageStartEvent, - RawMessageDeltaEvent, - RawMessageStopEvent, - RawContentBlockStartEvent, - RawContentBlockDeltaEvent, - RawContentBlockStopEvent, - ), - ) - ) or not isinstance( + if not isinstance( event, ( MessageStartEvent,