mirror of
https://github.com/browser-use/browser-use
synced 2026-04-22 17:45:09 +02:00
The main execution loop already wraps _execute_step with asyncio.wait_for using settings.step_timeout (default 180s). But _execute_initial_actions, which runs before the main loop, is unwrapped — if it hangs (e.g. the first navigate stalls on a silent CDP WebSocket before the per-action timeout can catch it), the agent blocks indefinitely without ever entering the main loop. No step gets recorded, history stays empty, and any outer watchdog eventually kills the run with zero diagnostic data. Wrap _execute_initial_actions with the same step_timeout. On timeout, record the failure in state.last_result / consecutive_failures and fall through to the main execution loop so the agent can still attempt to recover. InterruptedError (from an interrupting callback) is still swallowed silently — same contract as before. Paired with the per-action asyncio.wait_for added in tools/service.py, this closes the last unprotected path in the pre-main-loop flow.