From 66fa63820df5697569e702cf25a92b0b6891ed92 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Mon, 14 Sep 2026 20:30:31 +0530 Subject: [PATCH] fix(cli): flag the quiet -Q linger as consumed only after the loop runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _quiet_notify_linger_done was set BEFORE continue_quiet_notify_completions, so an exception between the flag and the loop's first wait made the finalize pass skip a linger that never ran (children SIGPIPE — the #90879 class). The flag now lands in a finally around the loop call: once the loop's first wait has started, budget is consumed and the finalize re-wait is correctly skipped; before that, an exception still lets finalize linger. --- cli.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/cli.py b/cli.py index a30db87344..8930152446 100644 --- a/cli.py +++ b/cli.py @@ -4121,13 +4121,18 @@ def _run_quiet_single_query(cli, effective_query): # One shared linger budget for the whole run: the loop below and the later # _wait_for_oneshot_background_completions pass must not each wait the full # oneshot_completion_wait_seconds on the same stuck notify_on_complete child. - cli._quiet_notify_linger_done = True - continued = continue_quiet_notify_completions( - getattr(cli, "session_id", "") or "", - _follow_up, - owns_event=getattr(cli, "_owns_process_notification", None), - linger_budget=quiet_notify_linger_seconds(), - ) + # Flagged after the loop (finally-equivalent): the wait is the loop's first + # statement, so anything raising past that point has consumed budget the + # finalize pass must not re-wait. + try: + continued = continue_quiet_notify_completions( + getattr(cli, "session_id", "") or "", + _follow_up, + owns_event=getattr(cli, "_owns_process_notification", None), + linger_budget=quiet_notify_linger_seconds(), + ) + finally: + cli._quiet_notify_linger_done = True if isinstance(continued, dict): result = continued response = result.get("final_response", "") if isinstance(result, dict) else str(result)