From a22dd4f488f8306b2e923d15cb149c981aab9351 Mon Sep 17 00:00:00 2001 From: ChenHao Chen Date: Mon, 30 Mar 2026 14:28:11 +0800 Subject: [PATCH] fix: add timeout to enable_domains during CDP connect to prevent hang on discarded tabs When connecting via --cdp to a browser with discarded/frozen tabs (Chrome Memory Saver), Page.enable hangs indefinitely because discarded tabs have no renderer process to respond. Add a 3-second timeout to the initial enable_domains call. If the first tab fails to respond (likely discarded), fall back to creating a new about:blank tab. Fixes #1036 --- cli/src/native/browser.rs | 47 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/cli/src/native/browser.rs b/cli/src/native/browser.rs index 1ac153908..98e6cc6b0 100644 --- a/cli/src/native/browser.rs +++ b/cli/src/native/browser.rs @@ -425,9 +425,54 @@ impl BrowserManager { }); } + // Try to enable domains on the first page with a timeout. + // Discarded/frozen tabs (Chrome Memory Saver) have no renderer, + // so Page.enable hangs forever. Fall back to a new tab if needed. self.active_page_index = 0; let session_id = self.pages[0].session_id.clone(); - self.enable_domains(&session_id).await?; + match tokio::time::timeout( + std::time::Duration::from_secs(3), + self.enable_domains(&session_id), + ) + .await + { + Ok(Ok(())) => {} + _ => { + // First tab is likely discarded — create a new tab + let result: CreateTargetResult = self + .client + .send_command_typed( + "Target.createTarget", + &CreateTargetParams { + url: "about:blank".to_string(), + }, + None, + ) + .await?; + + let attach_result: AttachToTargetResult = self + .client + .send_command_typed( + "Target.attachToTarget", + &AttachToTargetParams { + target_id: result.target_id.clone(), + flatten: true, + }, + None, + ) + .await?; + + self.pages.push(PageInfo { + target_id: result.target_id, + session_id: attach_result.session_id.clone(), + url: "about:blank".to_string(), + title: String::new(), + target_type: "page".to_string(), + }); + self.active_page_index = self.pages.len() - 1; + self.enable_domains(&attach_result.session_id).await?; + } + } } Ok(())