[Bug]: SSE client splits data lines on U+2028, U+2029 and U+0085, so streamed events fail to parse
Maintainer thường phản hồi trong vòng 2 ngày
Đánh giá
Issue này chưa được đánh giá.
Mô tả
What happened?
parse_sse_stream in src/a2a/client/transports/http_helpers.py reads the stream with response.aiter_lines() (line 78). httpx's line decoder follows str.splitlines(), so it also ends a line at U+2028 (LINE SEPARATOR), U+2029 (PARAGRAPH SEPARATOR) and U+0085 (NEL). SSE line ends are only CR, LF and CRLF, and the docstring on line 73 says the parser conforms to the SSE spec.
The server writes these three characters raw: json_utils.dumps uses ensure_ascii=False (src/a2a/utils/json_utils.py:19). sse-starlette frames on CR/LF only, so it sends one data: line. The client splits that line into several. json.loads fails on the first piece, and the stream ends with A2AClientError('Invalid JSON-RPC response in SSE stream').
Any string field in a streamed event can hold these characters, for example message text, artifacts or status messages that quote a document. Resubscribing sends the same task snapshot, so that task stays unreadable over streaming. Non-streaming GetTask is not affected. The same parser is used by the JSON-RPC and REST transports and by the v0.3 compat transports.
This looks like a regression from #1132, which removed httpx-sse. httpx-sse 0.4.3 split SSE lines on CR/LF only (_splitlines_sse).
Repro (library level, using the versions pinned in uv.lock: sse-starlette 3.4.4, httpx 0.28.1)
import asyncio, json
import httpx
from sse_starlette.sse import ServerSentEvent
async def main():
data = json.dumps({"text": "before
after"}, ensure_ascii=False)
frame = ServerSentEvent(data=data).encode()
print(frame.count(b"data:")) # 1: the server sends one data line
async def body():
yield frame
resp = httpx.Response(200, content=body())
lines = [l async for l in resp.aiter_lines()]
print(len(lines)) # 3: the client sees the data line split in two
json.loads(lines[0][len("data: "):])
asyncio.run(main())
Expected: one data: line that parses as JSON. Observed: JSONDecodeError.
Possible fixes:
- Split SSE lines on CR, LF and CRLF only, with a small line decoder over
aiter_text(). - Also, or instead: escape U+2028, U+2029 and U+0085 in
json_utils.dumps.
Related: #1213, the end-of-stream flush in the same parser.
No existing tests cover these characters in SSE data.
Relevant log output
json.decoder.JSONDecodeError: Unterminated string starting at: line 1 column 10 (char 9)
Code of Conduct
- I agree to follow this project's Code of Conduct
Drafted with Claude Code. I reviewed the code paths and ran the repro.
- Ngôn ngữ chính
- Python
- Star
- 2.2k
- Fork
- 532
- Merge trung bình
- 3 ngày 2 giờ
- Pull request đã merge (30 ngày)
- 46
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của a2aproject/a2a-python
-
[Bug]: `A2A-Version` validation ignores minor versions and the query parameterCó thể đã có người làm @rohityan đã nhận 74 ngày trước. Đang mởcomponent: server status:awaiting response status:stale
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
a2aproject/a2a-python#1204 · 4 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Bug]: REST task/request id sanitizationCó thể đã có người làm @Linux2010 đã nhận 133 ngày trước. Đang mởmaintainers-only
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
a2aproject/a2a-python#805 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
v0.3 REST and gRPC clients send blocking requests as non-blockingCó thể đã có người làm @ConnorMoss02 đã nhận 1 ngày trước. Đang mởcomponent: client
a2aproject/a2a-python#1428 · 1 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Compat REST client drops security from the v0.3 extended agent cardCó thể đã có người làm @ConnorMoss02 đã nhận 3 ngày trước. Đang mởcomponent: client status:awaiting response
a2aproject/a2a-python#1418 · 1 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Feat]: Add a task-state-invariants agent skill for sibling-surface propagationCó thể đã có người làm @Linux2010 đã nhận 5 ngày trước. Đang mởcomponent: tooling status:awaiting response
a2aproject/a2a-python#1413 · 3 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của a2aproject/a2a-python
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
NVIDIA/auto-ontology#463 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
NousResearch/hermes-agent#151165 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
Maintainer thường phản hồi trong vòng 1 ngày
-
code-health
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
tinaudio/synth-setter#3750 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] vllm-sr config migrate drops providers.models[].deploymentCó thể đã có người làm @Bevisy đã nhận hôm nay. Đang mởneeds-acceptance wg/developer-experience-ecosystem
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
vllm-project/semantic-router#5996 ·
Maintainer thường phản hồi trong vòng 2 ngày