From 64e66f6e0eafb1ead8004193c6ee6f33ae00097b Mon Sep 17 00:00:00 2001 From: Varun Nuthalapati Date: Tue, 28 Apr 2026 19:37:55 -0700 Subject: [PATCH] fix: handle COMError in wait_enabled when UI element becomes stale Selecting an option from a dropdown (or any interaction that triggers a UI change) can invalidate the underlying COM element. The subsequent call to control.is_enabled() then raises: _ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', ...) Wrap the is_enabled() poll in a try/except so that a stale-element COM error is treated as "ready" (with a warning) rather than crashing the agent loop. Closes #246 --- ufo/automator/ui_control/controller.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ufo/automator/ui_control/controller.py b/ufo/automator/ui_control/controller.py index 24ba147d0..4568c511f 100644 --- a/ufo/automator/ui_control/controller.py +++ b/ufo/automator/ui_control/controller.py @@ -365,7 +365,16 @@ def wait_enabled(self, timeout: int = 10, retry_interval: int = 0.5) -> None: :param timeout: The timeout to wait. :param retry_interval: The retry interval to wait. """ - while not self.control.is_enabled(): + while True: + try: + if self.control.is_enabled(): + break + except Exception as e: + logger.warning( + f"Exception while checking if control is enabled, " + f"assuming it is ready: {e}" + ) + break time.sleep(retry_interval) timeout -= retry_interval if timeout <= 0: