Skip to content

fix: guard ParsedMessageStopEvent.message type to suppress Pydantic warnings#1714

Open
lizradway wants to merge 1 commit into
anthropics:mainfrom
lizradway:fix/parsed-message-stop-event-pydantic-warnings
Open

fix: guard ParsedMessageStopEvent.message type to suppress Pydantic warnings#1714
lizradway wants to merge 1 commit into
anthropics:mainfrom
lizradway:fix/parsed-message-stop-event-pydantic-warnings

Conversation

@lizradway

@lizradway lizradway commented Jun 29, 2026

Copy link
Copy Markdown

model_dump() on ParsedMessageStopEvent emits PydanticSerializationUnexpectedValue warnings on every streamed response because the unresolved generic in message: ParsedMessage[ResponseFormatT] confuses Pydantic’s serializer at runtime (see Pydantic ref)

The fix is the same TYPE_CHECKING guard already used for ParsedContentBlockStopEvent.content_block right below, it was just missed here:

if TYPE_CHECKING:
    message: ParsedMessage[ResponseFormatT]
else:
    message: ParsedMessage

It looks like this inconsistency was introduced in ad56677 and only shows up at serialization time rather than typechecking or validation, likely explaining why this was not caught

Reproduced on every SDK version from 0.84.0 through 0.113.0 with pydantic 2.9–2.13.

Testing

Verified with the following across multiple SDK/pydantic version combinations:

import warnings
from anthropic.types.parsed_message import ParsedTextBlock, ParsedMessage
from anthropic.lib.streaming._types import ParsedMessageStopEvent
from anthropic._models import build
import anthropic

parsed_msg = ParsedMessage.construct(
    id="msg_test", type="message", role="assistant",
    content=[ParsedTextBlock.construct(type="text", text="Hello!")],
    model="claude-sonnet-4-20250514", stop_reason="end_turn",
    usage=anthropic.types.Usage.construct(input_tokens=10, output_tokens=5),
)
event = build(ParsedMessageStopEvent, type="message_stop", message=parsed_msg)

with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter("always")
    event.model_dump()

assert len(caught) == 0  # 12 sub-warnings before fix, 0 after

Also confirmed:

  • ruff check / ruff format pass
  • pyright / mypy pass with 0 errors
  • tests/test_streaming.py — 23 tests pass

Related: #1175, #1422
Resolves: #1715

Use TYPE_CHECKING guard on ParsedMessageStopEvent.message field to
prevent Pydantic from building a serializer schema that expects
ParsedTextBlock[TypeVar] in the content union. At runtime, the
unparameterized ParsedMessage avoids the type mismatch that causes
PydanticSerializationUnexpectedValue warnings on every streamed
response.

This follows the same pattern already used for
ParsedContentBlockStopEvent.content_block in the same file.
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.

[BUG] PydanticSerializationUnexpectedValue warnings on every message_stop event when streaming

1 participant