From 9d68a4250a3b4a61cfc8e92e34b8908a78ada6cb Mon Sep 17 00:00:00 2001 From: pefontana Date: Fri, 10 Apr 2026 16:58:42 -0300 Subject: [PATCH] fix(gateway): guard _agent_cache_lock access in reset handler Use getattr guard for _agent_cache_lock in _handle_reset_command because test fixtures may create GatewayRunner without calling __init__, leaving the attribute unset. Fixes e2e test failure: test_new_resets_session, test_new_then_status_reflects_reset, test_new_is_idempotent. --- gateway/run.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/gateway/run.py b/gateway/run.py index 5faf6dee063..9245c896ee7 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -3364,15 +3364,18 @@ class GatewayRunner: logger.debug("Gateway memory flush on reset failed: %s", e) # Close tool resources on the old agent (terminal sandboxes, browser # daemons, background processes) before evicting from cache. - with self._agent_cache_lock: - _cached = self._agent_cache.get(session_key) - _old_agent = _cached[0] if isinstance(_cached, tuple) else _cached if _cached else None - if _old_agent is not None: - try: - if hasattr(_old_agent, "close"): - _old_agent.close() - except Exception: - pass + # Guard with getattr because test fixtures may skip __init__. + _cache_lock = getattr(self, "_agent_cache_lock", None) + if _cache_lock is not None: + with _cache_lock: + _cached = self._agent_cache.get(session_key) + _old_agent = _cached[0] if isinstance(_cached, tuple) else _cached if _cached else None + if _old_agent is not None: + try: + if hasattr(_old_agent, "close"): + _old_agent.close() + except Exception: + pass self._evict_cached_agent(session_key) try: