Bug description
When the Ring server closes an active WebRTC live session (hang-up / session timeout), the reader task dies with RuntimeError: Task cannot await on itself and the exception is never retrieved. The close/error reason is also never forwarded to the on_message_callback, so the camera entity / card frontend never learns that the session ended (in my case: card buttons stayed greyed out and the card did not react until reload).
Environment
- Home Assistant Core 2026.9.1 (pins
ring-doorbell==0.9.14)
- ring-intercom-video integration v0.6.0b1
- python-ring-doorbell 0.9.14, Python 3.14
- Device: Ring Intercom, audio-only variant (
device_kind: intercom_handset_audio, audio_only: true)
Log output
2026-09-09 18:05:31.825 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved (task: None)
Traceback (most recent call last):
File "/usr/local/lib/python3.14/site-packages/ring_doorbell/webrtcstream.py", line 247, in reader
await self.handle_message(message)
File "/usr/local/lib/python3.14/site-packages/ring_doorbell/webrtcstream.py", line 423, in handle_message
await self.handle_close_message(message)
File "/usr/local/lib/python3.14/site-packages/ring_doorbell/webrtcstream.py", line 301, in handle_close_message
await self._close(closed_by_self=True)
File "/usr/local/lib/python3.14/site-packages/ring_doorbell/webrtcstream.py", line 378, in _close
await close_cb()
File "/config/custom_components/ring_intercom_camera/__init__.py", line 56, in _close_callback
await self.close_webrtc_stream(session_id)
File "/config/custom_components/ring_intercom_camera/__init__.py", line 77, in close_webrtc_stream
await stream.close()
File "/usr/local/lib/python3.14/site-packages/ring_doorbell/webrtcstream.py", line 370, in close
await self._close(closed_by_self=False)
File "/usr/local/lib/python3.14/site-packages/ring_doorbell/webrtcstream.py", line 392, in _close
await read_task
RuntimeError: Task cannot await on itself: <Task pending name='Task-2498' coro=<RingWebRtcStream.reader() running at /usr/local/lib/python3.14/site-packages/ring_doorbell/webrtcstream.py:247>>
Root cause: re-entrant close
- Ring sends a session
close message; the reader task receives it.
RingWebRtcStream.handle_close_message() (webrtcstream.py:294) calls await self._close(closed_by_self=True).
_close() invokes the integration's on_close_callback (webrtcstream.py:376-378) — still inside the reader task.
- The integration's callback (
_close_callback → close_webrtc_stream, __init__.py:55-77) calls await stream.close() on the same stream.
- That second
_close() reaches await read_task (webrtcstream.py:389-392) — but read_task is the task currently executing this code → RuntimeError: Task cannot await on itself.
Consequences:
- The reader task crashes with an unretrieved exception on every server-initiated close.
handle_close_message() never reaches self._on_message_callback(error_message) (webrtcstream.py:302-306), so the close/error reason is never delivered to the frontend.
Suggested fix
Avoid re-entering close() from within the close callback. The integration already has sync_close_webrtc_stream (__init__.py:79-83) which uses RingWebRtcStream.sync_close() — that schedules the close in a separate task and avoids the self-await. So in close_webrtc_stream:
async def close_webrtc_stream(self, session_id):
streams = _get_streams(self)
stream = streams.pop(session_id, None)
if stream:
stream.sync_close() # instead of: await stream.close()
Alternatively (or additionally) the lib could harden _close() itself, e.g. skip the await when re-entered from the reader: if not read_task.done() and read_task is not asyncio.current_task(): await read_task.
Reproduction
- Start a live session on an audio-only Intercom (card or the more-info dialog).
- End the session such that Ring sends the close message (hang up / let it time out) rather than closing only locally.
- Observe
Error doing job: Task exception was never retrieved + the RuntimeError in the logs; frontend keeps showing the stale session state.
Happy to test a patched build. Thanks for the integration — audio-only support in 0.6.0b1 works great otherwise (stable sub-second round-trip audio).
Bug description
When the Ring server closes an active WebRTC live session (hang-up / session timeout), the reader task dies with
RuntimeError: Task cannot await on itselfand the exception is never retrieved. The close/error reason is also never forwarded to theon_message_callback, so the camera entity / card frontend never learns that the session ended (in my case: card buttons stayed greyed out and the card did not react until reload).Environment
ring-doorbell==0.9.14)device_kind: intercom_handset_audio,audio_only: true)Log output
Root cause: re-entrant close
closemessage; the reader task receives it.RingWebRtcStream.handle_close_message()(webrtcstream.py:294) callsawait self._close(closed_by_self=True)._close()invokes the integration'son_close_callback(webrtcstream.py:376-378) — still inside the reader task._close_callback→close_webrtc_stream,__init__.py:55-77) callsawait stream.close()on the same stream._close()reachesawait read_task(webrtcstream.py:389-392) — butread_taskis the task currently executing this code →RuntimeError: Task cannot await on itself.Consequences:
handle_close_message()never reachesself._on_message_callback(error_message)(webrtcstream.py:302-306), so the close/error reason is never delivered to the frontend.Suggested fix
Avoid re-entering
close()from within the close callback. The integration already hassync_close_webrtc_stream(__init__.py:79-83) which usesRingWebRtcStream.sync_close()— that schedules the close in a separate task and avoids the self-await. So inclose_webrtc_stream:Alternatively (or additionally) the lib could harden
_close()itself, e.g. skip the await when re-entered from the reader:if not read_task.done() and read_task is not asyncio.current_task(): await read_task.Reproduction
Error doing job: Task exception was never retrieved+ theRuntimeErrorin the logs; frontend keeps showing the stale session state.Happy to test a patched build. Thanks for the integration — audio-only support in 0.6.0b1 works great otherwise (stable sub-second round-trip audio).