From c69f611d788f7080cc1cf28d8d49a4bf60e456b8 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Sat, 4 Apr 2026 11:12:35 -0500 Subject: [PATCH] Fix CDP attach hang on real browser sessions (Chrome 144+) (#1133) When connecting to a real, already-running browser (Chrome 144+) via CDP, targets may be paused waiting for the debugger after attach. Without an explicit Runtime.runIfWaitingForDebugger call, page-level commands hang indefinitely even though the WebSocket connection is live. Add Runtime.runIfWaitingForDebugger after Runtime.enable in all target attachment paths: enable_domains (covers initial attach, tab_new, tab_switch), enable_domains_direct (provider proxies), and the iframe auto-attach handler. The call is placed before Network.enable to avoid the documented deadlock when Network.enable precedes the resume. It is a no-op for targets that are not paused. Fixes #1130 Co-authored-by: ctate <366502+ctate@users.noreply.github.com> --- cli/src/native/actions.rs | 7 +++++++ cli/src/native/browser.rs | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/cli/src/native/actions.rs b/cli/src/native/actions.rs index ddf7ae5..012d5cd 100644 --- a/cli/src/native/actions.rs +++ b/cli/src/native/actions.rs @@ -581,6 +581,13 @@ impl DaemonState { self.iframe_sessions .insert(frame_id.clone(), iframe_sid.clone()); if let Some(ref mgr) = self.browser { + let _ = mgr + .client + .send_command_no_params( + "Runtime.runIfWaitingForDebugger", + Some(iframe_sid.as_str()), + ) + .await; let _ = mgr .client .send_command_no_params("DOM.enable", Some(iframe_sid.as_str())) diff --git a/cli/src/native/browser.rs b/cli/src/native/browser.rs index 6e7edec..fb23d1e 100644 --- a/cli/src/native/browser.rs +++ b/cli/src/native/browser.rs @@ -479,6 +479,13 @@ impl BrowserManager { self.client .send_command_no_params("Runtime.enable", Some(session_id)) .await?; + // Resume the target if it is paused waiting for the debugger. + // This is needed for real browser sessions (Chrome 144+) where targets + // are paused after attach until explicitly resumed. No-op otherwise. + let _ = self + .client + .send_command_no_params("Runtime.runIfWaitingForDebugger", Some(session_id)) + .await; self.client .send_command_no_params("Network.enable", Some(session_id)) .await?; @@ -508,6 +515,10 @@ impl BrowserManager { self.client .send_command_no_params("Runtime.enable", None) .await?; + let _ = self + .client + .send_command_no_params("Runtime.runIfWaitingForDebugger", None) + .await; self.client .send_command_no_params("Network.enable", None) .await?;