[GH-ISSUE #1384] [Bug] inspect_web_page rejects every target on Chromium 150: Page.getFrameTree reports the opaque placeholder URL #478

Closed
opened 2026-10-15 18:25:24 +00:00 by bsakaguchi · 5 comments
Owner

Originally created by @BaaRai on GitHub (Oct 10, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1384

Problem

On Chromium 150.0.7871.181 (current Kali/Debian build), npm run verify:browser fails at the first discovery gate:

BrowserObservationError: Browser observation inspect_web_page failed: target_not_allowed
    at CdpWebMcpDiscovery (allowedSanitizedUrl(initialUrl, origins) === undefined)

The main frame's URL read from Page.getFrameTree is no longer the real URL: Chromium 150 reports the opaque placeholder ":" (with securityOrigin: "://" and empty domainAndRegistry) for a committed, fully loaded same-origin page, so the origin allowlist check fails for every target and inspect_web_page rejects pages it is explicitly allowed to observe.

Protocol evidence

Same page (http://127.0.0.1:PORT/app?probe=1, committed, mimeType: text/html, loaderId present), headless Chromium 150.0.7871.181, one flat CDP session:

Source URL reported
Page.getFrameTree main frame ":" (masked placeholder)
Page.getNavigationHistory [""]
Target.getTargetInfo full real URL
HTTP /json endpoint full real URL

So the endpoint/target layer still knows the URL; the frame-tree layer masks it. I found no public CDP changelog or Chromium issue documenting this change yet, so it may be fresh, possibly a regression.

Affected surfaces (all consumers of frame URLs)

  • src/browser/CdpWebMcpDiscovery.ts: the initial and final allowedSanitizedUrl(mainFrameUrl(frameTree), origins) gates (lines ~63 and ~338) fail immediately.
  • src/browser/CdpCaptureDocuments.ts: captureFrames filters every frame through allowedSanitizedUrl(frame.url, ...), so frame scoping and evidence attribution degrade to excluded/unknown for all frames, not just the main one.
  • src/browser/CdpAuthorizedMainFrame.ts and the page-capture flow consume the same frame-tree URLs.

In other words this is not only the discovery gate: even with the gate bypassed, captures on Chromium 150 would filter every frame as origin-unknown.

Reproduction

  • REA_BROWSER_EXECUTABLE=/usr/bin/chromium REA_BROWSER_NO_SANDBOX=true npm run verify:browser on Linux x64 with Chromium 150.0.7871.181: fails at inspect_web_page target_not_allowed before any navigation assertions.
  • Minimal CDP probe (launch headless chromium with --remote-debugging-port=0, create a target against a local 127.0.0.1 server, attach, Page.enable, then the four sources in the table above). Happy to share the probe script.

Possible directions

  1. Treat an uninformative main-frame URL from the frame tree (no parseable scheme, exactly the ":" placeholder) as "unknown, not disallowed", and recover the authoritative URL from Target.getTargetInfo or the already-discovered endpoint target, keeping the allowlist enforced against that recovered URL.
  2. Same recovery applied to per-frame URLs for captures, with the unknown case disclosed as a limitation rather than an exclusion.
  3. If upstream confirms this is a Chromium regression that reverts, pin a known-good browser for the lane and track it here.

I can implement whichever direction you prefer; direction 1 plus 2 looks mechanical from the current call sites, but the truthful-vs-excluded semantics for masked frame URLs is a design call that belongs to you.

Originally created by @BaaRai on GitHub (Oct 10, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1384 ## Problem On Chromium 150.0.7871.181 (current Kali/Debian build), `npm run verify:browser` fails at the first discovery gate: ``` BrowserObservationError: Browser observation inspect_web_page failed: target_not_allowed at CdpWebMcpDiscovery (allowedSanitizedUrl(initialUrl, origins) === undefined) ``` The main frame's URL read from `Page.getFrameTree` is no longer the real URL: Chromium 150 reports the opaque placeholder `":"` (with `securityOrigin: "://"` and empty `domainAndRegistry`) for a committed, fully loaded same-origin page, so the origin allowlist check fails for every target and `inspect_web_page` rejects pages it is explicitly allowed to observe. ## Protocol evidence Same page (`http://127.0.0.1:PORT/app?probe=1`, committed, `mimeType: text/html`, `loaderId` present), headless Chromium 150.0.7871.181, one flat CDP session: | Source | URL reported | |---|---| | `Page.getFrameTree` main frame | `":"` (masked placeholder) | | `Page.getNavigationHistory` | `[""]` | | `Target.getTargetInfo` | full real URL | | HTTP `/json` endpoint | full real URL | So the endpoint/target layer still knows the URL; the frame-tree layer masks it. I found no public CDP changelog or Chromium issue documenting this change yet, so it may be fresh, possibly a regression. ## Affected surfaces (all consumers of frame URLs) - `src/browser/CdpWebMcpDiscovery.ts`: the initial and final `allowedSanitizedUrl(mainFrameUrl(frameTree), origins)` gates (lines ~63 and ~338) fail immediately. - `src/browser/CdpCaptureDocuments.ts`: `captureFrames` filters every frame through `allowedSanitizedUrl(frame.url, ...)`, so frame scoping and evidence attribution degrade to excluded/unknown for all frames, not just the main one. - `src/browser/CdpAuthorizedMainFrame.ts` and the page-capture flow consume the same frame-tree URLs. In other words this is not only the discovery gate: even with the gate bypassed, captures on Chromium 150 would filter every frame as origin-unknown. ## Reproduction - `REA_BROWSER_EXECUTABLE=/usr/bin/chromium REA_BROWSER_NO_SANDBOX=true npm run verify:browser` on Linux x64 with Chromium 150.0.7871.181: fails at `inspect_web_page target_not_allowed` before any navigation assertions. - Minimal CDP probe (launch headless chromium with `--remote-debugging-port=0`, create a target against a local 127.0.0.1 server, attach, `Page.enable`, then the four sources in the table above). Happy to share the probe script. ## Possible directions 1. Treat an uninformative main-frame URL from the frame tree (no parseable scheme, exactly the `":"` placeholder) as "unknown, not disallowed", and recover the authoritative URL from `Target.getTargetInfo` or the already-discovered endpoint target, keeping the allowlist enforced against that recovered URL. 2. Same recovery applied to per-frame URLs for captures, with the unknown case disclosed as a limitation rather than an exclusion. 3. If upstream confirms this is a Chromium regression that reverts, pin a known-good browser for the lane and track it here. I can implement whichever direction you prefer; direction 1 plus 2 looks mechanical from the current call sites, but the truthful-vs-excluded semantics for masked frame URLs is a design call that belongs to you.
bsakaguchi 2026-10-15 18:25:24 +00:00
Author
Owner

@CassieFox23 commented on GitHub (Oct 10, 2026):

TL;DR: It did not reproduce on full Chromium 154 (BSD-3-Clause) in --headless=new mode. Your report is on 150, so that is still open.

Edit: added the Chromium license.

What ran:

  • Binary: full Chromium, /usr/bin/chromium-browser.
  • Version: 154.0.8037.57, Fedora 44 build.
  • Mode: --headless=new, sandbox on.
  • Page: a small HTML page from a 127.0.0.1 server.
  • Probe: one flat CDP session, like yours.
Source URL reported
Page.getFrameTree main frame full real URL
Page.getFrameTree child frame full real URL
securityOrigin http://127.0.0.1:PORT
Page.getNavigationHistory full real URL
Target.getTargetInfo full real URL
/json/list full real URL

I did not see the ":" placeholder.

I also ran the rea CLI from main (08ec2bf8). inspect-web-page passed. It listed all frames with real URLs.

The headless_shell build of 154 gave the same clean result.

The open difference is 150 versus 154. It may be a bug that 154 fixed. It may also be specific to the Debian or Kali build.

I looked upstream too. I found no Chromium bug for this. The CDP schema for Page.Frame has not changed this year.

I did not run npm run verify:browser here.

Test setup
  • Box: Fedora-based Linux x64

🤖 Generated with Claude Code (Opus 5.5) 🦊

<!-- gh-comment-id:6091610357 --> @CassieFox23 commented on GitHub (Oct 10, 2026): **TL;DR:** It did not reproduce on full [Chromium 154](https://github.com/chromium/chromium) ([BSD-3-Clause](https://github.com/chromium/chromium/blob/main/LICENSE)) in `--headless=new` mode. Your report is on 150, so that is still open. Edit: added the Chromium license. What ran: - Binary: full Chromium, `/usr/bin/chromium-browser`. - Version: 154.0.8037.57, Fedora 44 build. - Mode: `--headless=new`, sandbox on. - Page: a small HTML page from a 127.0.0.1 server. - Probe: one flat CDP session, like yours. | Source | URL reported | |---|---| | `Page.getFrameTree` main frame | full real URL | | `Page.getFrameTree` child frame | full real URL | | `securityOrigin` | `http://127.0.0.1:PORT` | | `Page.getNavigationHistory` | full real URL | | `Target.getTargetInfo` | full real URL | | `/json/list` | full real URL | I did not see the `":"` placeholder. I also ran the `rea` CLI from main (08ec2bf8). `inspect-web-page` passed. It listed all frames with real URLs. The `headless_shell` build of 154 gave the same clean result. The open difference is 150 versus 154. It may be a bug that 154 fixed. It may also be specific to the Debian or Kali build. I looked upstream too. I found no Chromium bug for this. The CDP schema for `Page.Frame` has not changed this year. I did not run `npm run verify:browser` here. <details> <summary>Test setup</summary> - Box: Fedora-based Linux x64 </details> 🤖 Generated with Claude Code (Opus 5.5) 🦊
Author
Owner

@CassieFox23 commented on GitHub (Oct 10, 2026):

TL;DR: One more check. REA's own browser test passes on Chromium 154 (BSD-3-Clause). So 154 does not show this bug for me.

Edit: added the Chromium license.

I ran npm run verify:browser on main (08ec2bf8).

  • Browser: full Chromium, the Fedora 44 build.
  • Version: 154.0.8037.57.
  • Set with REA_BROWSER_EXECUTABLE=/usr/bin/chromium-browser.
  • Result: exit 0, "verified": true.
  • No target_not_allowed anywhere in the log.
  • It took about 1.5 minutes, build included.

One tip for anyone else who runs it. Keep TMPDIR short. My first try used a long temp path. Chromium then aborted with "Socket path too long". That was my setup, not REA.

The open question is still 150 versus 154. It could also be the Debian or Kali build.

Test setup
  • Node: 24.18.0

🤖 Generated with Claude Code (Opus 5.5) 🦊

<!-- gh-comment-id:6091695981 --> @CassieFox23 commented on GitHub (Oct 10, 2026): **TL;DR:** One more check. REA's own browser test passes on [Chromium 154](https://github.com/chromium/chromium) ([BSD-3-Clause](https://github.com/chromium/chromium/blob/main/LICENSE)). So 154 does not show this bug for me. Edit: added the Chromium license. I ran `npm run verify:browser` on main (`08ec2bf8`). - Browser: full Chromium, the Fedora 44 build. - Version: 154.0.8037.57. - Set with `REA_BROWSER_EXECUTABLE=/usr/bin/chromium-browser`. - Result: exit 0, `"verified": true`. - No `target_not_allowed` anywhere in the log. - It took about 1.5 minutes, build included. One tip for anyone else who runs it. Keep `TMPDIR` short. My first try used a long temp path. Chromium then aborted with "Socket path too long". That was my setup, not REA. The open question is still 150 versus 154. It could also be the Debian or Kali build. <details> <summary>Test setup</summary> - Node: 24.18.0 </details> 🤖 Generated with Claude Code (Opus 5.5) 🦊
Author
Owner

@BaaRai commented on GitHub (Oct 10, 2026):

Update with a fuller root-cause matrix and a working fix branch for the gating surfaces.

The mask is not a 150-only regression and not the Debian/Kali build: it is the official Google builds. Same flat CDP session, same local page, --headless=new:

Build getFrameTree main frame securityOrigin getNavigationHistory
Kali/Debian Chromium 150.0.7871.181 ":" "://" [""]
Official Chrome-for-Testing 150.0.7871.124 ":" "://" [""]
Official Chrome-for-Testing 154.0.8037.57 "" (empty string) "://" [""]
Fedora 44 distro Chromium 154.0.8037.57 (CassieFox23's run) full real URL real full

So 154 still masks in the official builds, just with a different placeholder, and the sandbox flag makes no difference (probed both ways). Whatever distinguishes the Fedora package from the Google builds also exists in both 150 and 154. Unmodified main fails verify:browser on official CfT 154 exactly like on 150. Beyond the frame tree, the same masking hits DOMSnapshot (documents carry no documentURL) and the storage agents: DOMStorage.getDOMStorageItems rejects with -32000 "Frame not found for the given storage id", IndexedDB.requestDatabaseNames with -32000 "No document for given frame found", CacheStorage.requestCacheNames with -32602 "No frame found for given storage key", and the deeper fingerprint probes never respond at all.

Fix branch: fix/cdp-masked-main-frame-url on my fork (commit 23744663). Design: whenever a frame-tree URL carries no URL evidence at all (":", "", unparseable), scope resolution falls back to the target URL that authorizeCdpTarget already gated the attach on; a parsed but out-of-scope origin still rejects, and parseable non-HTTP pages such as about:blank keep their existing wait semantics. Applied to: the discovery gates (initial and final), authorizedMainFrame (all three call sites), the root frame in captureFrames, the attached/completed main-frame URLs, and the leading DOM document in captureDom. Storage probes now disclose browser-side command rejections as limitations (matching the sibling IndexedDB/CacheStorage semantics) and skip the fingerprint probes once their own discovery was unavailable, which also removes the stall. No behavior change when the frame tree reports real URLs.

Where it stands on official CfT 154: the lane went from failing on the first inspect_web_page call to running the whole pipeline and now failing at Real Chrome script metadata was missing (the script capture surfaces, and presumably resources, filter by masked URLs the same way). Finishing those is mechanical per surface, or a unified authorized-origin resolution pass if you prefer that shape; happy to complete it either way on your call.

<!-- gh-comment-id:6093170242 --> @BaaRai commented on GitHub (Oct 10, 2026): Update with a fuller root-cause matrix and a working fix branch for the gating surfaces. **The mask is not a 150-only regression and not the Debian/Kali build: it is the official Google builds.** Same flat CDP session, same local page, `--headless=new`: | Build | getFrameTree main frame | securityOrigin | getNavigationHistory | |---|---|---|---| | Kali/Debian Chromium 150.0.7871.181 | `":"` | `"://"` | `[""]` | | Official Chrome-for-Testing 150.0.7871.124 | `":"` | `"://"` | `[""]` | | Official Chrome-for-Testing 154.0.8037.57 | `""` (empty string) | `"://"` | `[""]` | | Fedora 44 distro Chromium 154.0.8037.57 (CassieFox23's run) | full real URL | real | full | So 154 still masks in the official builds, just with a different placeholder, and the sandbox flag makes no difference (probed both ways). Whatever distinguishes the Fedora package from the Google builds also exists in both 150 and 154. Unmodified main fails `verify:browser` on official CfT 154 exactly like on 150. Beyond the frame tree, the same masking hits `DOMSnapshot` (documents carry no documentURL) and the storage agents: `DOMStorage.getDOMStorageItems` rejects with -32000 "Frame not found for the given storage id", `IndexedDB.requestDatabaseNames` with -32000 "No document for given frame found", `CacheStorage.requestCacheNames` with -32602 "No frame found for given storage key", and the deeper fingerprint probes never respond at all. **Fix branch: `fix/cdp-masked-main-frame-url` on my fork (commit 23744663).** Design: whenever a frame-tree URL carries no URL evidence at all (`":"`, `""`, unparseable), scope resolution falls back to the target URL that `authorizeCdpTarget` already gated the attach on; a parsed but out-of-scope origin still rejects, and parseable non-HTTP pages such as `about:blank` keep their existing wait semantics. Applied to: the discovery gates (initial and final), `authorizedMainFrame` (all three call sites), the root frame in `captureFrames`, the attached/completed main-frame URLs, and the leading DOM document in `captureDom`. Storage probes now disclose browser-side command rejections as limitations (matching the sibling IndexedDB/CacheStorage semantics) and skip the fingerprint probes once their own discovery was unavailable, which also removes the stall. No behavior change when the frame tree reports real URLs. Where it stands on official CfT 154: the lane went from failing on the first `inspect_web_page` call to running the whole pipeline and now failing at `Real Chrome script metadata was missing` (the script capture surfaces, and presumably resources, filter by masked URLs the same way). Finishing those is mechanical per surface, or a unified authorized-origin resolution pass if you prefer that shape; happy to complete it either way on your call.
Author
Owner

@CassieFox23 commented on GitHub (Oct 10, 2026):

TL;DR: Google's own test build of 154 shows real URLs on my box. So the mask is not the build alone. Something else on the machine turns it on.

I got the same version you named. It is Google's official Chrome for Testing build, 154.0.8037.57. I ran our probe on it. Then I ran npm run verify:browser from main.

Build, all 154.0.8037.57 Frame URL Origin History main verify:browser
Google test build real real real pass, 2 of 2
Fedora Chromium (BSD-3-Clause) real real real pass

Both builds report the same source revision. The CI lane also uses a Google build. It is Google Chrome 154.0.8037.97. Other PRs pass verify:browser there today.

No flag brought the mask back. I tried these on both builds:

  • headless new, old and plain
  • sandbox on and off
  • site isolation on and off
  • field trials off

So I don't know what turns it on for you. It is not the build by itself. It may be something about the box. Could you share how you start the browser? The full command line would help. So would the user it runs as. Any browser policy files would help too.

I also tested PR #1411. Its latest head, 08a6aab5, passes verify:browser on the Fedora build here. The head before it passed on both builds. The details are on the PR.

Not run:

  • Any Kali or Debian build.
  • Google Chrome .97 on this box. I only read it from CI logs.
  • Headed mode, with a window.
  • BaaRai's own probe script.

Thanks, BaaRai, for the full table. It made this easy to check.

Flags tried

Each row ran on both builds. Every row showed real URLs.

Flags
--headless=new --enable-automation
--headless=new
--headless=new --no-sandbox
--headless=old
--headless
--headless=new --disable-site-isolation-trials
--headless=new --site-per-process
--headless=new --disable-field-trial-config

The probe also passes --no-first-run --no-default-browser-check --disable-background-networking --disable-component-update --disable-sync and its own profile folder. The Fedora rows used the bare binary, not the wrapper script.

154 took --headless=old. I did not check that it changed mode.

Raw output

Google test build, --headless=new:

Browser.getVersion: {"product":"Chrome/154.0.8037.57", ...}
Page.getFrameTree main  url: "http://127.0.0.1:36397/app?startup=1" securityOrigin: "http://127.0.0.1:36397"
Page.getFrameTree child url: "http://127.0.0.1:36397/child" securityOrigin: "http://127.0.0.1:36397"
Page.getNavigationHistory urls: ["http://127.0.0.1:36397/app?startup=1"]
Target.getTargetInfo url: "http://127.0.0.1:36397/app?startup=1"

Both builds report revision 73c14f62.

The CI image is ubuntu-24.04 20261004.327. Its readme lists Google Chrome 154.0.8037.97. A passing run on it (38016194351) ends with "browser":"Chrome/154.0.8037.97" and "verified":true.

Commands
node probe.mjs <browser> --headless=new [flags]
REA_BROWSER_EXECUTABLE=<browser> TMPDIR=<short dir> npm run verify:browser

The test build came from the official known-good versions list, linux64 zip. It ran from a temp folder. I deleted it after.

Test setup
  • Box: Nobara 44 (Fedora 44 base), Linux 7.2.9
  • CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads
  • RAM: 32 GB DDR4-3600
  • Node: 24.18.0
  • Main: 7aa4d768
  • Chromium (BSD-3-Clause): the one from Fedora 44, at 154.0.8037.57
  • Google's official Chrome for Testing build: the zip for Linux, at 154.0.8037.57

🤖 Generated with Claude Code (Opus 5.5) 🦊

<!-- gh-comment-id:6093598441 --> @CassieFox23 commented on GitHub (Oct 10, 2026): **TL;DR:** Google's own test build of 154 shows real URLs on my box. So the mask is not the build alone. Something else on the machine turns it on. I got the same version you named. It is Google's official Chrome for Testing build, 154.0.8037.57. I ran our probe on it. Then I ran `npm run verify:browser` from main. | Build, all 154.0.8037.57 | Frame URL | Origin | History | main `verify:browser` | |---|---|---|---|---| | Google test build | real | real | real | pass, 2 of 2 | | Fedora [Chromium](https://github.com/chromium/chromium) ([BSD-3-Clause](https://github.com/chromium/chromium/blob/main/LICENSE)) | real | real | real | pass | Both builds report the same source revision. The CI lane also uses a Google build. It is Google Chrome 154.0.8037.97. Other PRs pass `verify:browser` there today. No flag brought the mask back. I tried these on both builds: - headless new, old and plain - sandbox on and off - site isolation on and off - field trials off So I don't know what turns it on for you. It is not the build by itself. It may be something about the box. Could you share how you start the browser? The full command line would help. So would the user it runs as. Any browser policy files would help too. I also tested PR #1411. Its latest head, `08a6aab5`, passes `verify:browser` on the Fedora build here. The head before it passed on both builds. The details are on the PR. **Not run:** - Any Kali or Debian build. - Google Chrome .97 on this box. I only read it from CI logs. - Headed mode, with a window. - BaaRai's own probe script. Thanks, BaaRai, for the full table. It made this easy to check. <details> <summary>Flags tried</summary> Each row ran on both builds. Every row showed real URLs. | Flags | |---| | `--headless=new --enable-automation` | | `--headless=new` | | `--headless=new --no-sandbox` | | `--headless=old` | | `--headless` | | `--headless=new --disable-site-isolation-trials` | | `--headless=new --site-per-process` | | `--headless=new --disable-field-trial-config` | The probe also passes `--no-first-run --no-default-browser-check --disable-background-networking --disable-component-update --disable-sync` and its own profile folder. The Fedora rows used the bare binary, not the wrapper script. 154 took `--headless=old`. I did not check that it changed mode. </details> <details> <summary>Raw output</summary> Google test build, `--headless=new`: ``` Browser.getVersion: {"product":"Chrome/154.0.8037.57", ...} Page.getFrameTree main url: "http://127.0.0.1:36397/app?startup=1" securityOrigin: "http://127.0.0.1:36397" Page.getFrameTree child url: "http://127.0.0.1:36397/child" securityOrigin: "http://127.0.0.1:36397" Page.getNavigationHistory urls: ["http://127.0.0.1:36397/app?startup=1"] Target.getTargetInfo url: "http://127.0.0.1:36397/app?startup=1" ``` Both builds report revision `73c14f62`. The CI image is ubuntu-24.04 `20261004.327`. Its readme lists Google Chrome 154.0.8037.97. A passing run on it (38016194351) ends with `"browser":"Chrome/154.0.8037.97"` and `"verified":true`. </details> <details> <summary>Commands</summary> ``` node probe.mjs <browser> --headless=new [flags] REA_BROWSER_EXECUTABLE=<browser> TMPDIR=<short dir> npm run verify:browser ``` The test build came from the official known-good versions list, linux64 zip. It ran from a temp folder. I deleted it after. </details> <details> <summary>Test setup</summary> - Box: Nobara 44 (Fedora 44 base), Linux 7.2.9 - CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads - RAM: 32 GB DDR4-3600 - Node: 24.18.0 - Main: `7aa4d768` - [Chromium](https://github.com/chromium/chromium) ([BSD-3-Clause](https://github.com/chromium/chromium/blob/main/LICENSE)): the one from Fedora 44, at 154.0.8037.57 - Google's official Chrome for Testing build: the zip for Linux, at 154.0.8037.57 </details> 🤖 Generated with Claude Code (Opus 5.5) 🦊
Author
Owner

@BaaRai commented on GitHub (Oct 10, 2026):

You were right to push on this, and the official-builds claim in my matrix was wrong. Same version, same revision as your runs, clean on your box, masked on mine. It is the machine, and I found the switch tonight.

It is the session bus. Bisecting my shell environment variable by variable against the same CfT 154 binary and flags:

Environment Main-frame URL
normal session env "" (masked)
env -i, minimal vars real
env -i + DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus "" (masked)
same, plus --password-store=basic real
normal env + --password-store=basic real
normal env + NO_AT_BRIDGE=1 "" (masked)

Nothing is being masked. The page never loads. With the bus reachable, the page reports from inside itself: readyState "complete", location.href "about:blank", empty body text. A --log-net-log capture of the startup contains zero URL requests and zero proxy events. The startup navigation is simply never issued.

The machine detail: this box runs WSL with an XFCE desktop session, so /run/user/1000/bus is live and gnome-keyring is on it, but the login keyring is locked, no PAM unlock ever happened for it. Headless Chrome reaches the keyring during profile startup, the daemon creates an unlock prompt, and a prompt that can never be answered headless means startup never finishes. The daemon's object tree now literally lists one pending prompt object per probe run (p1..p9, one for each time I launched a "masked" probe). Chrome's stderr only shows an unrelated NetworkManager query failing, which is why nothing pointed at the keyring until the bisect.

That explains every observation, including why we saw different things:

  • my box: live bus + locked keyring, so every Chromium build stalls (Kali distro 150 reports ":" and official CfT 150/154 report "", the placeholder just differs by version)
  • your box: desktop session where the keyring unlocks at login, so Chrome's keyring call answers instantly and pages load; that is also why no flag brought "the mask" back for you, there is no mask to bring back
  • CI ubuntu runners: no session bus in the runner environment at all

Fix. Verification browsers never need a real keyring, so the lanes should not depend on desktop keyring state: PR #1432 passes --password-store=basic in both raw launchers and documents the failure mode. Proof from this box: main plus that one flag runs the complete verify:browser green, "browser": "Chrome/154.0.8037.57", "verified": true, zero target_not_allowed.

PR #1411 is withdrawn and I am closing it. Its fallbacks made the lane appear to work by authorizing capture of a page that had not loaded, using the attach-authorized target URL as a stand-in. That is fail-open against exactly this failure mode. REA failing closed here was the correct behavior; the defect was in my browser launch environment all along. Thanks for the push, the revision comparison is what sent me bisecting the environment instead of the binaries.

<!-- gh-comment-id:6093781686 --> @BaaRai commented on GitHub (Oct 10, 2026): You were right to push on this, and the official-builds claim in my matrix was wrong. Same version, same revision as your runs, clean on your box, masked on mine. It is the machine, and I found the switch tonight. **It is the session bus.** Bisecting my shell environment variable by variable against the same CfT 154 binary and flags: | Environment | Main-frame URL | |---|---| | normal session env | "" (masked) | | env -i, minimal vars | real | | env -i + DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus | "" (masked) | | same, plus --password-store=basic | real | | normal env + --password-store=basic | real | | normal env + NO_AT_BRIDGE=1 | "" (masked) | **Nothing is being masked. The page never loads.** With the bus reachable, the page reports from inside itself: readyState "complete", location.href "about:blank", empty body text. A --log-net-log capture of the startup contains zero URL requests and zero proxy events. The startup navigation is simply never issued. The machine detail: this box runs WSL with an XFCE desktop session, so /run/user/1000/bus is live and gnome-keyring is on it, but the login keyring is locked, no PAM unlock ever happened for it. Headless Chrome reaches the keyring during profile startup, the daemon creates an unlock prompt, and a prompt that can never be answered headless means startup never finishes. The daemon's object tree now literally lists one pending prompt object per probe run (p1..p9, one for each time I launched a "masked" probe). Chrome's stderr only shows an unrelated NetworkManager query failing, which is why nothing pointed at the keyring until the bisect. That explains every observation, including why we saw different things: - my box: live bus + locked keyring, so every Chromium build stalls (Kali distro 150 reports ":" and official CfT 150/154 report "", the placeholder just differs by version) - your box: desktop session where the keyring unlocks at login, so Chrome's keyring call answers instantly and pages load; that is also why no flag brought "the mask" back for you, there is no mask to bring back - CI ubuntu runners: no session bus in the runner environment at all **Fix.** Verification browsers never need a real keyring, so the lanes should not depend on desktop keyring state: PR #1432 passes --password-store=basic in both raw launchers and documents the failure mode. Proof from this box: main plus that one flag runs the complete verify:browser green, "browser": "Chrome/154.0.8037.57", "verified": true, zero target_not_allowed. **PR #1411 is withdrawn and I am closing it.** Its fallbacks made the lane appear to work by authorizing capture of a page that had not loaded, using the attach-authorized target URL as a stand-in. That is fail-open against exactly this failure mode. REA failing closed here was the correct behavior; the defect was in my browser launch environment all along. Thanks for the push, the revision comparison is what sent me bisecting the environment instead of the binaries.
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#478
No description provided.