Skip to content

fix(query): guard malformed inbound frames and send control error response - #1538

Open
yniantongtian-oss wants to merge 1 commit into
anthropics:mainfrom
yniantongtian-oss:fix/malformed-frames-1515
Open

yniantongtian-oss wants to merge 1 commit into
anthropics:mainfrom
yniantongtian-oss:fix/malformed-frames-1515

Conversation

@yniantongtian-oss

Copy link
Copy Markdown

Closes #1515

Summary

Guards Query against malformed inbound frames from the transport so they no longer crash the background _read_messages loop with KeyError, AttributeError, or TypeError, and ensures malformed control_request payloads with a valid request_id receive an error control_response.

Changes

  • src/claude_agent_sdk/_internal/query.py
    • Query._read_messages: Drop non-dict frames with a warning; validate control_response (response is a dict with non-empty str request_id), control_request (non-empty str request_id before spawning handler), control_cancel_request (non-empty str request_id before .pop()), and transcript_mirror (non-empty str filePath and list entries before enqueue).
    • Query._handle_control_request: Guard missing/invalid request_id, and move request (dict) and subtype (non-empty str) validation inside the try block so malformed payloads send a control_response with subtype: error over transport.write.
    • Query._track_task_lifecycle: Validate task_id is a non-empty str (logging a warning on non-None non-string task_id) and ensure task_type / status are str before checking membership in DEFERRING_TASK_TYPES and TERMINAL_TASK_STATUSES.
  • tests/test_query.py
    • Added TestMalformedFrames covering dropped malformed frames, unhashable control_cancel_request IDs with inflight requests, malformed transcript_mirror and system task lifecycle frames, and malformed control_request error responses across both asyncio and trio backends.

Verification

  • ruff check src/ tests/ scripts/ — passed
  • ruff format --check src/ tests/ scripts/ — passed
  • mypy src/ scripts/ — passed (Success: no issues found in 34 source files)
  • pytest tests/test_query.py tests/test_transcript_mirror.py tests/test_tool_callbacks.py --no-cov — 245 passed
  • pytest tests/ --no-cov (Windows win32, Python 3.13.14) — 1753 passed, 21 skipped

This branch has not been deployed

No deployments
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.

Malformed frames kill the read loop; malformed control_request gets no error response

1 participant