Summary
Stopping hermes dashboard with Ctrl-C while the Kanban dashboard is open can print an ASGI traceback from the dashboard event stream. The stream handler is cancelled during normal shutdown while sleeping in its poll loop, but asyncio.CancelledError is surfaced as an application error.
Repro
- Run
hermes --yolo dashboard.
- Open the dashboard Web UI.
- Stop the dashboard with Ctrl-C while the page is still connected.
Observed
Uvicorn prints an application traceback ending in the Kanban dashboard event stream:
plugins/kanban/dashboard/plugin_api.py, in stream_events
await asyncio.sleep(_EVENT_POLL_SECONDS)
asyncio.exceptions.CancelledError
There can also be a lifespan cancellation traceback after Ctrl-C.
Expected
Dashboard shutdown or browser disconnect should be quiet, or at most debug-level noise. This is a normal cancellation path, not an application failure.
Suggested fix
Handle asyncio.CancelledError beside WebSocketDisconnect and return without warning:
except WebSocketDisconnect:
return
except asyncio.CancelledError:
return
Notes
This does not look like data loss or task corruption. It is control-plane polish: normal dashboard exit currently looks like a runtime failure, which makes operator debugging noisier than it needs to be.
Summary
Stopping
hermes dashboardwith Ctrl-C while the Kanban dashboard is open can print an ASGI traceback from the dashboard event stream. The stream handler is cancelled during normal shutdown while sleeping in its poll loop, butasyncio.CancelledErroris surfaced as an application error.Repro
hermes --yolo dashboard.Observed
Uvicorn prints an application traceback ending in the Kanban dashboard event stream:
There can also be a lifespan cancellation traceback after Ctrl-C.
Expected
Dashboard shutdown or browser disconnect should be quiet, or at most debug-level noise. This is a normal cancellation path, not an application failure.
Suggested fix
Handle
asyncio.CancelledErrorbesideWebSocketDisconnectand return without warning:Notes
This does not look like data loss or task corruption. It is control-plane polish: normal dashboard exit currently looks like a runtime failure, which makes operator debugging noisier than it needs to be.