Skip to content

RuntimeError: Unexpected ASGI message 'websocket.send', after sending 'websocket.close' or response already completed. #33

@MarcSkovMadsen

Description

@MarcSkovMadsen

I've created an Panel application which basically works as described below.

We've defined a global instance of

class DataStore(param.Parameterized):
     value = param.DataFrame()

global_data_store = DataStore()

The global_data_store.value is updated every 3 seconds from a loop running in a separate thread. Every application then displays the DataFrame in a table Tabulator(value=global_data_store.param.value, ....). The Tabulator table is inside a layout in the main area of a FastListTemplate.

When ever I reload the page I see

RuntimeError: Unexpected ASGI message 'websocket.send', after sending 'websocket.close' or response already completed.
2025-08-17 17:28:27,445 | ERROR | tornado.application | Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x7f57735b1710>>, <Task finished name='Task-49128' coro=<ServerSession.with_document_locked() done, defined at /home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/bokeh/server/session.py:77> exception=RuntimeError("Unexpected ASGI message 'websocket.send', after sending 'websocket.close' or response already completed.")>)
Traceback (most recent call last):
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/tornado/ioloop.py", line 758, in _run_callback
    ret = callback()
          ^^^^^^^^^^
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/tornado/ioloop.py", line 782, in _discard_future_result
    future.result()
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/bokeh/server/session.py", line 106, in _needs_document_lock_wrapper
    await p
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/bokeh_fastapi/handler.py", line 355, in send_message
    await self._socket.send_text(message.header_json)
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/starlette/websockets.py", line 166, in send_text
    await self.send({"type": "websocket.send", "text": data})
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/starlette/websockets.py", line 86, in send
    await self._send(message)
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/starlette/_exception_handler.py", line 39, in sender
    await send(message)
  File "/home/jovyan/repos/revenue-price-gui/.venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 360, in asgi_send
    raise RuntimeError(msg % message_type)
RuntimeError: Unexpected ASGI message 'websocket.send', after sending 'websocket.close' or response already completed.

I will try to provide minimum, reproducible code when/ if I get the time. But I believe it could be possible from this explanation to find the place where messages continues to be send after websocket.close has been sent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions