Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/claude_agent_sdk/_internal/message_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def parse_message(data: dict[str, Any]) -> Message:
content=content_blocks,
model=data["message"]["model"],
parent_tool_use_id=data.get("parent_tool_use_id"),
error=data["message"].get("error"),
error=data.get("error"),
)
except KeyError as e:
raise MessageParseError(
Expand Down
48 changes: 48 additions & 0 deletions tests/test_message_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,54 @@ def test_parse_assistant_message_inside_subagent(self):
assert isinstance(message, AssistantMessage)
assert message.parent_tool_use_id == "toolu_01Xrwd5Y13sEHtzScxR77So8"

def test_parse_assistant_message_with_error(self):
"""Test parsing an assistant message with error field (issue #505).

The error field is at the top-level of the JSON, not inside the message object.
This enables applications to detect API errors like rate limits.
"""
data = {
"type": "assistant",
"message": {
"content": [{"type": "text", "text": "API Error: 404 ..."}],
"model": "<synthetic>",
},
"session_id": "test-session",
"uuid": "test-uuid",
"error": "unknown", # error is at top level, not inside message
}
message = parse_message(data)
assert isinstance(message, AssistantMessage)
assert message.error == "unknown"

def test_parse_assistant_message_with_rate_limit_error(self):
"""Test parsing an assistant message with rate_limit error."""
data = {
"type": "assistant",
"message": {
"content": [{"type": "text", "text": "Rate limit exceeded"}],
"model": "<synthetic>",
},
"error": "rate_limit",
}
message = parse_message(data)
assert isinstance(message, AssistantMessage)
assert message.error == "rate_limit"

def test_parse_assistant_message_with_auth_error(self):
"""Test parsing an assistant message with authentication_failed error."""
data = {
"type": "assistant",
"message": {
"content": [{"type": "text", "text": "Invalid API key"}],
"model": "<synthetic>",
},
"error": "authentication_failed",
}
message = parse_message(data)
assert isinstance(message, AssistantMessage)
assert message.error == "authentication_failed"

def test_parse_valid_result_message(self):
"""Test parsing a valid result message."""
data = {
Expand Down