From 26e3fc8fcc5040afe0bfd0251a882e6b4f1075f9 Mon Sep 17 00:00:00 2001 From: Altynbek Orumbayev Date: Fri, 10 Apr 2026 09:11:01 +0200 Subject: [PATCH] fix: skip blank/whitespace-only lines in receive loop _receive_loop only checked for EOF (b""), but blank lines like b"\n" or b"\r\n" are truthy and reached json.loads(), causing JSONDecodeError. Strip each line and skip when empty before parsing. --- src/acp/connection.py | 3 +++ tests/test_rpc.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/acp/connection.py b/src/acp/connection.py index aca1c19..8f4c401 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -151,6 +151,9 @@ async def _receive_loop(self) -> None: line = await self._reader.readline() if not line: break + line = line.strip() + if not line: + continue try: message: dict[str, Any] = json.loads(line) except Exception: diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 0d3bb75..7c44441 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -316,6 +316,20 @@ async def test_ignore_invalid_messages(connect, server): await asyncio.wait_for(server.client_reader.readline(), timeout=0.1) +@pytest.mark.asyncio +async def test_blank_lines_skipped(connect, server): + connect(connect_agent=True, connect_client=False) + + for noise in [b"\n", b" \n", b"\r\n"]: + server.client_writer.write(noise) + req = {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": 1}} + server.client_writer.write((json.dumps(req) + "\n").encode()) + await server.client_writer.drain() + + resp = json.loads(await asyncio.wait_for(server.client_reader.readline(), timeout=1)) + assert resp["id"] == 1 and "result" in resp + + class _ExampleAgent(Agent): __test__ = False