[GH-ISSUE #5266] [Bug] Browser scenario start waits for load with no deadline when the page navigates away before load #3214

Open
opened 2026-10-31 00:37:57 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @mipiverse-llc on GitHub (Oct 19, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5266

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Process capture or runtime observation

Observed behavior

Opening a browser scenario waits for the start page's load event with no deadline of its own. PlaywrightScenarioSession.ts:203-210 (at aacf740a0) calls page.goto(start_url, { waitUntil: "load", timeout: 0 }) inside withPlaywrightExecutionBoundary(..., undefined, options.signal). Only the caller's signal can end that wait.

If the start page's script starts a navigation before load, and that navigation never commits, goto does not settle. That happens when the next host never answers, or when the request is aborted. Nothing then reaches assertBlocked, storage.settle, or the first step.

This is source-derived for REA itself. The Playwright behavior underneath was observed with a standalone script, described below.

Reproduction

I did not run this through rea. It is a standalone Playwright 1.58.2 script (the version REA pins), with Google Chrome headless and the same goto options. timeout is 10 s instead of 0 so the script ends.

  1. Route https://start.example/ to <p>start</p><script>setTimeout(()=>{location.href="https://away.example/"}, D)</script><img src="https://start.example/slow.png">, with the image answered after 1.5 s.
  2. Route https://away.example/ in one of three ways: answer it, never answer, or route.abort("aborted").
  3. await page.goto("https://start.example/", { waitUntil: "load", timeout: 10_000 }).

Results, one run each:

D away.example goto
0 ms answered resolved after 36 ms, on away.example
0 ms never answers timed out after 10,002 ms
0 ms aborted timed out after 10,000 ms
100 ms aborted timed out after 10,003 ms
3,000 ms (after load) aborted resolved after 1,517 ms

With timeout: 0, as in REA, the two failing cases would wait until the caller aborts.

Expected behavior

My expectation, not verified against a documented contract: opening the scenario should end within a bounded time even when the start page navigates away early. Two possible ways:

  • wait for commit, then wait for document.readyState === "complete" under the same signal and a provider-owned deadline;
  • or report a start-navigation timeout as a failed open, with cleanup.

docs/browser-scenario-contract.md says navigation timeouts "remain fixed provider-owned liveness limits". The start navigation has none (related wording report: #3423).

Impact and scope

A target page can hold a scenario open indefinitely when no caller deadline is set, or until the caller's deadline when one is. It needs only an early redirect to a host that does not answer. I did not measure how often real sites do this. I did not check whether every CLI and MCP path passes a signal, so the worst case for each interface is unknown.

REA version

source aacf740a0 (morluto/rea main, 2026-10-19), source-inspected; the Playwright run used playwright-core 1.58.2

Runtime and platform

Node v26.9.0; macOS 27.0 arm64; Google Chrome (stable), headless

Target and artifact context

Any web page whose script navigates before load

Interface

Other (browser scenario start, shared by CLI and MCP; source-inspected)

Earliest failure stage

Capture or observation

Originally created by @mipiverse-llc on GitHub (Oct 19, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5266 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Process capture or runtime observation ### Observed behavior Opening a browser scenario waits for the start page's `load` event with no deadline of its own. `PlaywrightScenarioSession.ts:203-210` (at `aacf740a0`) calls `page.goto(start_url, { waitUntil: "load", timeout: 0 })` inside `withPlaywrightExecutionBoundary(..., undefined, options.signal)`. Only the caller's `signal` can end that wait. If the start page's script starts a navigation before `load`, and that navigation never commits, `goto` does not settle. That happens when the next host never answers, or when the request is aborted. Nothing then reaches `assertBlocked`, `storage.settle`, or the first step. This is source-derived for REA itself. The Playwright behavior underneath was observed with a standalone script, described below. ### Reproduction I did not run this through `rea`. It is a standalone Playwright 1.58.2 script (the version REA pins), with Google Chrome headless and the same `goto` options. `timeout` is 10 s instead of 0 so the script ends. 1. Route `https://start.example/` to `<p>start</p><script>setTimeout(()=>{location.href="https://away.example/"}, D)</script><img src="https://start.example/slow.png">`, with the image answered after 1.5 s. 2. Route `https://away.example/` in one of three ways: answer it, never answer, or `route.abort("aborted")`. 3. `await page.goto("https://start.example/", { waitUntil: "load", timeout: 10_000 })`. Results, one run each: | `D` | `away.example` | `goto` | |---|---|---| | 0 ms | answered | resolved after 36 ms, on `away.example` | | 0 ms | never answers | timed out after 10,002 ms | | 0 ms | aborted | timed out after 10,000 ms | | 100 ms | aborted | timed out after 10,003 ms | | 3,000 ms (after `load`) | aborted | resolved after 1,517 ms | With `timeout: 0`, as in REA, the two failing cases would wait until the caller aborts. ### Expected behavior My expectation, not verified against a documented contract: opening the scenario should end within a bounded time even when the start page navigates away early. Two possible ways: - wait for `commit`, then wait for `document.readyState === "complete"` under the same signal and a provider-owned deadline; - or report a start-navigation timeout as a failed open, with cleanup. `docs/browser-scenario-contract.md` says navigation timeouts "remain fixed provider-owned liveness limits". The start navigation has none (related wording report: #3423). ### Impact and scope A target page can hold a scenario open indefinitely when no caller deadline is set, or until the caller's deadline when one is. It needs only an early redirect to a host that does not answer. I did not measure how often real sites do this. I did not check whether every CLI and MCP path passes a `signal`, so the worst case for each interface is unknown. ### REA version source `aacf740a0` (morluto/rea main, 2026-10-19), source-inspected; the Playwright run used playwright-core 1.58.2 ### Runtime and platform Node v26.9.0; macOS 27.0 arm64; Google Chrome (stable), headless ### Target and artifact context Any web page whose script navigates before `load` ### Interface Other (browser scenario start, shared by CLI and MCP; source-inspected) ### Earliest failure stage Capture or observation
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3214
No description provided.