Skip to content

fix: tolerate thinking blocks without a signature#1073

Open
Magic-Man-us wants to merge 1 commit into
anthropics:mainfrom
Magic-Man-us:fix/thinking-block-parsing
Open

fix: tolerate thinking blocks without a signature#1073
Magic-Man-us wants to merge 1 commit into
anthropics:mainfrom
Magic-Man-us:fix/thinking-block-parsing

Conversation

@Magic-Man-us

Copy link
Copy Markdown

Summary

Fixes #949. The message parser hard-indexed block["signature"] when constructing a ThinkingBlock, so an assistant message containing an unsigned thinking block (emitted by some Anthropic-compatible backends) raised MessageParseError: Missing required field in assistant message: 'signature' and aborted the entire query.

While fixing it I found a related gap: the user-message branch of the parser had no thinking case at all, so thinking blocks replayed inside a user message (e.g. on session resume) were silently dropped.

Changes

  • _internal/message_parser.py — parse the signature with block.get("signature", "") in the assistant branch (no longer crashes on absence).
  • _internal/message_parser.py — add a thinking case to the user-message branch so replayed thinking blocks are preserved instead of dropped.
  • types.py — default ThinkingBlock.signature to "", reflecting that the field may be absent on the wire.
  • tests/test_message_parser.py — add tests for the unsigned-assistant-thinking case and the user-branch thinking case.

Test plan

  • ruff check src/ tests/ — clean
  • ruff format --check src/ tests/ — clean
  • mypy src/ — clean
  • pytest tests/ — 987 passed, 5 skipped

The message parser hard-indexed block["signature"] when building a
ThinkingBlock, so an assistant message containing an unsigned thinking
block (emitted by some Anthropic-compatible backends) raised
MessageParseError and aborted the whole query (anthropics#949). The user-message
branch also had no thinking case, silently dropping thinking blocks
replayed on resume.

- Parse signature with block.get("signature", "") in both the assistant
  and user content branches.
- Add a thinking case to the user-message branch so replayed thinking
  blocks are preserved.
- Default ThinkingBlock.signature to "" to reflect that it may be absent
  on the wire.
- Add parser tests for the unsigned-assistant and user-branch cases.

Fixes anthropics#949
Copilot AI review requested due to automatic review settings June 27, 2026 19:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes parsing compatibility with Anthropic-compatible backends that emit thinking content blocks without a signature, and ensures thinking blocks are preserved when replayed inside user messages (e.g., resume/session replay).

Changes:

  • Make signature optional when parsing assistant thinking blocks (defaults to "" when absent).
  • Preserve thinking blocks in the user-message parsing branch.
  • Update ThinkingBlock to default signature to "" and add regression tests for both scenarios.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/claude_agent_sdk/_internal/message_parser.py Uses block.get("signature", "") for thinking blocks and adds a thinking case to user content parsing.
src/claude_agent_sdk/types.py Defaults ThinkingBlock.signature to "" to reflect optional presence on the wire.
tests/test_message_parser.py Adds tests covering unsigned assistant thinking blocks and thinking blocks within user messages.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

MessageParseError: missing signature in thinking block with claude-agent-sdk 0.1.79 and Anthropic-compatible backend

2 participants