-
Notifications
You must be signed in to change notification settings - Fork 71
:keep-alive messages causing a2a-sdk (Python) client to crash #99
Copy link
Copy link
Description
What happened?
The go-sdk periodically sends :keep-alive messages. While this is valid for SSE, it causes many a2a-python clients to crash because they cannot parse it correctly.
For example, when using the client from https://github.com/a2aproject/a2a-samples/tree/main/samples/python/hosts/cli to access a long-running streaming request from a go-sdk server, it will crash. I printed the message that causes the parsing error, and it's an empty string (''). I believe this corresponds to the :keep-alive message.
Relevant log output
Traceback (most recent call last):
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/a2a/client/transports/jsonrpc.py", line 167, in send_message_streaming
json.loads(sse.data)
~~~~~~~~~~^^^^^^^^^^
File "/root/.local/share/uv/python/cpython-3.13.9-linux-x86_64-gnu/lib/python3.13/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
~~~~~~~~~~~~~~~~~~~~~~~^^^
File "/root/.local/share/uv/python/cpython-3.13.9-linux-x86_64-gnu/lib/python3.13/json/decoder.py", line 345, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.local/share/uv/python/cpython-3.13.9-linux-x86_64-gnu/lib/python3.13/json/decoder.py", line 363, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/root/a2a-samples/samples/python/hosts/cli/__main__.py", line 297, in <module>
asyncio.run(cli())
~~~^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/asyncclick/core.py", line 1515, in __call__
return anyio.run(self._main, main, args, kwargs, backend=_anyio_backend)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/anyio/_core/_eventloop.py", line 74, in run
return async_backend.run(func, args, {}, backend_options)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 2316, in run
return runner.run(wrapper())
~~~~~~~~~~^^^^^^^^^^^
File "/root/.local/share/uv/python/cpython-3.13.9-linux-x86_64-gnu/lib/python3.13/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/root/.local/share/uv/python/cpython-3.13.9-linux-x86_64-gnu/lib/python3.13/asyncio/base_events.py", line 725, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 2304, in wrapper
return await func(*args)
^^^^^^^^^^^^^^^^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/asyncclick/core.py", line 1526, in _main
return await main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/asyncclick/core.py", line 1425, in main
rv = await self.invoke(ctx)
^^^^^^^^^^^^^^^^^^^^^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/asyncclick/core.py", line 1288, in invoke
return await ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/asyncclick/core.py", line 855, in invoke
rv = await rv
^^^^^^^^
File "/root/a2a-samples/samples/python/hosts/cli/__main__.py", line 110, in cli
continue_loop, _, task_id = await completeTask(
^^^^^^^^^^^^^^^^^^^
...<7 lines>...
)
^
File "/root/a2a-samples/samples/python/hosts/cli/__main__.py", line 199, in completeTask
async for result in response_stream:
...<20 lines>...
print(f'stream event => {event.model_dump_json(exclude_none=True)}')
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/a2a/client/legacy.py", line 125, in send_message_streaming
async for result in self._transport.send_message_streaming(
...<6 lines>...
)
File "/root/a2a-samples/samples/python/.venv/lib/python3.13/site-packages/a2a/client/transports/jsonrpc.py", line 177, in send_message_streaming
raise A2AClientJSONError(f"{str(e)} - Raw data: {sse.data!r}") from e
a2a.client.errors.A2AClientJSONError: JSON Error: Expecting value: line 1 column 1 (char 0) - Raw data: ''Code of Conduct
- I agree to follow this project's Code of Conduct
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels