WebSocket event delivery can stall permanently while prompts continue executing successfully
- Dominant language
- Python
- Stars
- 133k
- Forks
- 15.7k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 158
Description
### Custom Node Testing
- [x] I have tried disabling custom nodes and the issue persists (see [how to disable custom nodes](https://docs.comfy.org/troubleshooting/custom-node-issues#step-1%3A-test-with-all-custom-nodes-disabled) if you need help)
### Expected Behavior
A connected client should receive execution events and the binary output for
the submitted prompt. One stale or blocked WebSocket connection should not
prevent event delivery to other clients indefinitely.
### Actual Behavior
### Summary
After a long-running ComfyUI process, WebSocket event delivery stopped working while the HTTP API and prompt execution continued to work normally.
Clients could connect to `/ws` and receive the initial `status` message. Prompts submitted through `/prompt` were accepted and completed successfully, and `/history/{prompt_id}` reported `execution_success`. However, the WebSocket client received no subsequent execution events or binary image frames and eventually timed out in `ws.recv()`.
Restarting ComfyUI restored WebSocket delivery.
### Environment
- OS: Linux
- ComfyUI runtime version: `0.26.0`
- Approximate process uptime when failure occurred: 27 days
- Python: `3.12.2`
- PyTorch: `2.11.0+cu130`
- Launch command:
```bash
python main.py --port 8008 --cuda-device 1 --listen
### Steps to Reproduce
GET /queue returned immediately and showed an empty queue.
A client connected to /ws?clientId=.
The client received the initial WebSocket status event.
POST /prompt returned a valid prompt_id with no node errors.
The workflow completed successfully in approximately 25 seconds.
/history/{prompt_id} contained execution_success.
The WebSocket received no execution_start, executing,
execution_success, or binary image frames.
ws.recv() eventually raised:websocket._exceptions.WebSocketTimeoutException: Connection timed out
This was also reproduced with a newly generated client UUID and a minimal
workflow using EmptyImage and SaveImageWebsocket, so it did not appear to
be specific to the original workflow or client ID reuse.
### Debug Logs
```powershell
anaconda3/envs/comfyc/lib/python3.12/site-packages/websocket/_socket.py", line 120, in recv
raise WebSocketTimeoutException("Connection timed out")
websocket._exceptions.WebSocketTimeoutException: Connection timed out
```
### Other
## Relevant implementation
`PromptServer.send_sync()` places messages into an `asyncio.Queue`:
```python
def send_sync(self, event, data, sid=None):
self.loop.call_soon_threadsafe(
self.messages.put_nowait, (event, data, sid))
```
`publish_loop()` sends queued messages serially:
```python
async def publish_loop(self):
while True:
msg = await self.messages.get()
await self.send(*msg)
```
Socket writes have no explicit timeout:
```python
async def send_socket_catch_exception(function, message):
try:
await function(message)
except (...):
logging.warning(...)
```
A socket write that never completes could therefore block `publish_loop`. An unexpected exception could also terminate it without per-message recovery.
Contributor guide
Research direction
Trace PromptServer.send_sync(), publish_loop(), and send_socket_catch_exception() first. Reproduce the issue with the minimal EmptyImage and SaveImageWebsocket workflow, then verify that a stalled or failing socket cannot stop delivery to other clients and that execution events and binary frames still arrive after successful prompt completion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100