@@ -141,6 +141,50 @@ async def handle_with_lock():
141141 f"Failed to initialize new page: { str (e )} " , category = "context"
142142 )
143143
144+ async def _handle_page_close (self , closing_page : StagehandPage ):
145+ """
146+ Handle page close events and update the active page if needed.
147+ Uses the page switch lock to prevent race conditions with ongoing operations.
148+ """
149+ try :
150+ async def handle_with_lock ():
151+ async with self .stagehand ._page_switch_lock :
152+ if self .active_stagehand_page is not closing_page :
153+ return
154+
155+ remaining_pages = self ._context .pages
156+ if remaining_pages :
157+ first_remaining = remaining_pages [0 ]
158+ new_active = self .page_map .get (first_remaining )
159+ if new_active :
160+ self .set_active_page (new_active )
161+ self .stagehand .logger .debug (
162+ f"Active page closed, switching to: { first_remaining .url } " ,
163+ category = "context" ,
164+ )
165+ else :
166+ self .stagehand .logger .warning (
167+ "Could not find StagehandPage wrapper for remaining page" ,
168+ category = "context" ,
169+ )
170+ else :
171+ self .active_stagehand_page = None
172+ self .stagehand .logger .debug (
173+ "Active page closed and no pages remaining" ,
174+ category = "context" ,
175+ )
176+
177+ await asyncio .wait_for (handle_with_lock (), timeout = 30 )
178+ except asyncio .TimeoutError :
179+ self .stagehand .logger .error (
180+ "Timeout waiting for page switch lock when handling page close" ,
181+ category = "context" ,
182+ )
183+ except Exception as e :
184+ self .stagehand .logger .error (
185+ f"Failed to handle page close: { str (e )} " , category = "context"
186+ )
187+
144188 def __getattr__ (self , name ):
145189 # Forward attribute lookups to the underlying BrowserContext
146190 attr = getattr (self ._context , name )
@@ -220,11 +264,13 @@ def on_frame_navigated(params):
220264 # Register the event listener
221265 cdp_session .on ("Page.frameNavigated" , on_frame_navigated )
222266
223- # Clean up frame ID when page closes
224267 def on_page_close ():
225268 if stagehand_page .frame_id :
226269 self .unregister_frame_id (stagehand_page .frame_id )
227270
271+ if self .active_stagehand_page is stagehand_page :
272+ asyncio .create_task (self ._handle_page_close (stagehand_page ))
273+
228274 pw_page .once ("close" , on_page_close )
229275
230276 except Exception as e :
0 commit comments