From ada59d73e631cef1836f346b6fea088e29db571e Mon Sep 17 00:00:00 2001 From: keyos Date: Tue, 19 May 2026 20:56:17 +0000 Subject: [PATCH] fix(approval): simplify gateway_keys expression and document race window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the redundant 'if gw_data else []' guard — gw_data is already guaranteed to be a dict by the 'or {}' fallback above. Add a one-line comment explaining the peek-without-pop race window: a concurrent resolver may pop a different gateway entry, but approve_session is idempotent over the session key set so the outcome is the same regardless. --- api/routes.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 097de890..73a9427e 100644 --- a/api/routes.py +++ b/api/routes.py @@ -8784,7 +8784,12 @@ def _resolve_approval_legacy(sid: str, approval_id: str, choice: str) -> bool: # _gateway_queues stores _ApprovalEntry objects; their # .data dict carries command, pattern_key, pattern_keys. gw_data = getattr(gw_entry, 'data', None) or {} - gateway_keys = gw_data.get("pattern_keys") or [gw_data.get("pattern_key", "")] if gw_data else [] + gateway_keys = gw_data.get("pattern_keys") or [gw_data.get("pattern_key", "")] + # Peek is not strict — a concurrent resolver may pop a + # different gateway entry before we reach + # resolve_gateway_approval below, but approve_session is + # idempotent over the session key set so the outcome is + # the same regardless of which entry wins the race. found_target = True # Notify SSE subscribers of the new head (or empty state) so the UI # surfaces any trailing approvals that were queued behind this one