From 73a6b80317652a63faad3d8f0917e38e82cf8175 Mon Sep 17 00:00:00 2001 From: sprmn24 Date: Mon, 27 Apr 2026 22:31:33 +0300 Subject: [PATCH] fix(browser_supervisor): verify thread and loop health before returning cached supervisor _SupervisorRegistry.get_or_start() returned an existing supervisor whenever the cdp_url matched, without checking if the supervisor's thread or event loop was still alive. A crashed supervisor would be silently reused, causing missed dialog/frame updates. Now checks both _thread.is_alive() and _loop.is_running() before returning the cached instance. An unhealthy supervisor is torn down and recreated, matching the existing URL-changed code path. --- tools/browser_supervisor.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/browser_supervisor.py b/tools/browser_supervisor.py index 91d7e78621..db0b1e2990 100644 --- a/tools/browser_supervisor.py +++ b/tools/browser_supervisor.py @@ -1304,8 +1304,12 @@ class _SupervisorRegistry: existing = self._by_task.get(task_id) if existing is not None: if existing.cdp_url == cdp_url: - return existing - # URL changed — tear down old, fall through to re-create. + thread_ok = existing._thread is not None and existing._thread.is_alive() + loop_ok = existing._loop is not None and existing._loop.is_running() + if thread_ok and loop_ok: + return existing + # Unhealthy — tear down and recreate. + # URL changed or unhealthy — tear down, fall through to re-create. self._by_task.pop(task_id, None) if existing is not None: existing.stop()