parse_message silently drops image content blocks from user messages
Summary
The content-block loops in parse_message (src/claude_agent_sdk/_internal/message_parser.py) have no default case, so any block type outside the handled set is dropped without a trace. The concrete victim is the image block: a user message with a pasted image parses to a UserMessage whose content is silently missing the image. There is no ImageBlock in the type model, no log line, and no way for a consumer to know the block existed.
Reproduction
from claude_agent_sdk._internal.message_parser import parse_message
data = {
"type": "user",
"message": {
"content": [
{"type": "text", "text": "What is in this screenshot?"},
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "iVBORw0KGgo..."}},
]
},
}
msg = parse_message(data)
print(len(msg.content)) # 1 on main; the image block is goneThis is the real wire shape: Claude Code emits exactly this for user messages with attached images. Verified against an actual Claude Code session transcript containing a pasted screenshot ({"type": "image", "source": {"type": "base64", "media_type": "image/png", ...}} at the top level of message.content): 2 raw blocks parse to 1 on main.
Why it is a bug rather than a modeling choice
- Unknown message types are handled forward-compatibly with a debug log (
message_parser.py, the finalcase _). Unknown block types get no log at all, so the two paths are inconsistent. - Images inside
tool_resultcontent survive, becauseToolResultBlock.contentpasses the inner list through raw. Only top-level image blocks are lost, so a screenshot returned by a tool is visible to a consumer while a screenshot pasted by the user is not. - Any SDK consumer that inspects or re-processes user turns (logging, mirroring, analytics, session replay) silently loses the image content.
Expected behavior
Image blocks parse to a typed block that preserves the source payload, and still-unknown block types are skipped with a debug log like unknown message types are.
Environment
main @ 3cb0f73, Python 3.12.10, Windows. Full test suite with the fix below: 1370 passed, 14 skipped; ruff and mypy clean.
PR with the fix: #1276
Source: anthropics/claude-agent-sdk-python