[GH-ISSUE #4425] [Bug] inspect-web-page: requests from dedicated workers are not recorded (worker listed as attached, 0 requests) #1758

Open
opened 2026-10-16 21:09:53 +00:00 by bsakaguchi · 3 comments
Owner

Originally created by @Rbbit23 on GitHub (Oct 16, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4425

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

With rea inspect-web-page attached over CDP to a page target, network requests made by the page are recorded, but requests made by a dedicated Web Worker are not, although REA lists that worker as attached and attributes it to the allowed origin. Workers created after the attach are neither listed nor recorded.

Command: rea inspect-web-page http://127.0.0.1:9222 <TARGET_ID> --observation-ms 60000 --format json
Counts by distinct marker in the output (60 s window): page 6/6, long-lived worker 0/6, new short-lived workers 0/6.

Reproduction

Ran once (one 60 s window). Dedicated Chrome profile, debugging port bound to 127.0.0.1:
--remote-debugging-port=9222 --user-data-dir=<dedicated dir>
Env: REA_BROWSER_OBSERVE_ENABLED=true, REA_BROWSER_CDP_ENDPOINTS_JSON='["http://127.0.0.1:9222"]', REA_BROWSER_ALLOWED_ORIGINS_JSON='["https://<origin>"]'

  1. On a page of https://<origin> (our own site), ran in the console. It fires one request every 10 s for 6 minutes from: the page; a long-lived blob worker created before attach; a new blob worker per round. Markers are in the query parameter NAME because values are redacted:
(() => {
  const lungoSrc = "let n=0;const t=setInterval(()=>{n++;const k=n;fetch('https://<origin>/_app/version.json?rea_worker_lungo_'+k,{cache:'no-store'}).then(r=>postMessage('lungo '+k+' '+r.status));if(n>=36)clearInterval(t);},10000);";
  const lungo = new Worker(URL.createObjectURL(new Blob([lungoSrc], { type: 'text/javascript' })));
  lungo.onmessage = (e) => console.log('[canary-worker]', e.data);
  let i = 0;
  const t = setInterval(() => {
    i++; const k = i;
    fetch('/_app/version.json?rea_pagina_' + k, { cache: 'no-store' }).then(r => console.log('[canary-pagina]', k, r.status));
    const src = "fetch('https://<origin>/_app/version.json?rea_worker_nuovo_" + k + "',{cache:'no-store'}).then(r=>postMessage(r.status))";
    const w = new Worker(URL.createObjectURL(new Blob([src], { type: 'text/javascript' })));
    w.onmessage = (e) => { console.log('[canary-nuovo]', k, e.data); w.terminate(); };
    if (i >= 36) clearInterval(t);
  }, 10000);
})();
  1. rea list-browser-targets http://127.0.0.1:9222 --format json → 1 page target on the origin
  2. rea inspect-web-page http://127.0.0.1:9222 <TARGET_ID> --observation-ms 60000 --format json > inspect.json (exit 0, no stderr)
  3. grep -oE "rea_(pagina|worker_lungo|worker_nuovo)_[0-9]+" inspect.json | sort -u

Expected behavior

About 6 distinct markers of each kind in the 60 s window, or an explicit limitation saying that worker network activity is not covered. Unverified expectation: the 6.5.0 npm package ships no docs, and docs/browser-observation.md on main (not available at tag v6.5.0) says the capture includes workers and attach-window network, without saying whether worker network is included.

Impact and scope

Observed: when an app does its work in a worker, "0 network requests" from inspect-web-page can be read as "the app made no requests", while the worker did make them. Tested once, one origin, Chrome 155 on macOS, blob: dedicated workers only. Not tested: same-origin script workers, shared workers, service workers, other browsers. Severity unknown.

REA version

6.5.0 (npm, provenance attestation verified; installed with --omit=optional --ignore-scripts)

Runtime and platform

Node v24.15.0; npm 11.12.1; macOS (architecture not recorded); Chrome 155.0.8059.80

Target and artifact context

CDP page target (https origin) with dedicated Web Workers created from blob: URLs

Interface

CLI

Earliest failure stage

Capture or observation

Relevant output or evidence

Obtained from inspect.json of the run above (values redacted):

  • normalized_result.workers: 1 entry, type "worker", url blob:https://<origin>/<uuid>, origin https://<origin>, attached: true, parent_frame_id = the page target → supports "the worker was attached"
  • distinct markers: rea_pagina 6, rea_worker_lungo 0, rea_worker_nuovo 0 → supports "worker requests not recorded"
  • completeness.status "policy_filtered"; attach_limited_sections includes "network_requests"; no excluded entry for workers or network

Cross-checks in the same browser (the requests did happen):

  • the console logged HTTP 200 for every page and worker marker
  • the DevTools Network panel showed the worker requests (gear icon, initiator blob:)
  • chrome://net-export recorded all markers: page 6/6, long-lived worker 6/6, new workers 6/6 (separate run, same snippet shortened to 6 rounds every 5 s)

Typed outcome or recovery expected

Either worker requests in normalized_result.network.requests (with the worker's target id), or a limitation/completeness entry stating that worker network activity is not observed, so that an empty result is not mistaken for "no requests".

Analysis or suspected cause

Hypothesis only, not source-derived (we did not read REA's source): Network.enable may not be sent on worker sessions, and auto-attach may not cover workers created during the window.

Additional context

  • Related but different: #883 (worker source/runtime attribution), #3378 (worker inventory reported as empty), #2956 and #2166 (worker / service-worker handling under attached-scenario policies). This report is about a dedicated worker's NETWORK requests not being recorded by inspect-web-page while the worker itself is listed as attached.
  • A HAR exported from the DevTools Network panel also omits the worker requests even though the panel shows them, so the HAR path (inspect-web-network-capture) is blind to worker traffic too. This is Chrome behavior, not REA, but may be worth a note in the HAR docs.
  • Minor (docs): the 6.5.0 npm package ships no docs, and docs/browser-observation.md is not available at tag v6.5.0.
  • Proposal, NOT run: a shorter origin-independent snippet that should reproduce on any https origin:
(() => {
  const o = location.origin;
  new Worker(URL.createObjectURL(new Blob(["let n=0;const t=setInterval(()=>{n++;fetch('" + o + "/?rea_worker_long_'+n,{cache:'no-store'});if(n>=36)clearInterval(t);},10000);"], { type: 'text/javascript' })));
  let i = 0;
  const t = setInterval(() => {
    i++;
    fetch(o + '/?rea_page_' + i, { cache: 'no-store' });
    new Worker(URL.createObjectURL(new Blob(["fetch('" + o + "/?rea_worker_new_" + i + "',{cache:'no-store'}).then(()=>close())"], { type: 'text/javascript' })));
    if (i >= 36) clearInterval(t);
  }, 10000);
})();

Thanks for REA: the passive design, the evidence IDs and the honest limitations field made this easy to pin down.

Originally created by @Rbbit23 on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4425 ### 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 With `rea inspect-web-page` attached over CDP to a page target, network requests made by the page are recorded, but requests made by a dedicated Web Worker are not, although REA lists that worker as attached and attributes it to the allowed origin. Workers created after the attach are neither listed nor recorded. Command: rea inspect-web-page http://127.0.0.1:9222 <TARGET_ID> --observation-ms 60000 --format json Counts by distinct marker in the output (60 s window): page 6/6, long-lived worker 0/6, new short-lived workers 0/6. ### Reproduction Ran once (one 60 s window). Dedicated Chrome profile, debugging port bound to 127.0.0.1: `--remote-debugging-port=9222 --user-data-dir=<dedicated dir>` Env: `REA_BROWSER_OBSERVE_ENABLED=true`, `REA_BROWSER_CDP_ENDPOINTS_JSON='["http://127.0.0.1:9222"]'`, `REA_BROWSER_ALLOWED_ORIGINS_JSON='["https://<origin>"]'` 1. On a page of `https://<origin>` (our own site), ran in the console. It fires one request every 10 s for 6 minutes from: the page; a long-lived blob worker created before attach; a new blob worker per round. Markers are in the query parameter NAME because values are redacted: ```js (() => { const lungoSrc = "let n=0;const t=setInterval(()=>{n++;const k=n;fetch('https://<origin>/_app/version.json?rea_worker_lungo_'+k,{cache:'no-store'}).then(r=>postMessage('lungo '+k+' '+r.status));if(n>=36)clearInterval(t);},10000);"; const lungo = new Worker(URL.createObjectURL(new Blob([lungoSrc], { type: 'text/javascript' }))); lungo.onmessage = (e) => console.log('[canary-worker]', e.data); let i = 0; const t = setInterval(() => { i++; const k = i; fetch('/_app/version.json?rea_pagina_' + k, { cache: 'no-store' }).then(r => console.log('[canary-pagina]', k, r.status)); const src = "fetch('https://<origin>/_app/version.json?rea_worker_nuovo_" + k + "',{cache:'no-store'}).then(r=>postMessage(r.status))"; const w = new Worker(URL.createObjectURL(new Blob([src], { type: 'text/javascript' }))); w.onmessage = (e) => { console.log('[canary-nuovo]', k, e.data); w.terminate(); }; if (i >= 36) clearInterval(t); }, 10000); })(); ``` 2. rea list-browser-targets http://127.0.0.1:9222 --format json → 1 page target on the origin 3. rea inspect-web-page http://127.0.0.1:9222 <TARGET_ID> --observation-ms 60000 --format json > inspect.json (exit 0, no stderr) 4. grep -oE "rea_(pagina|worker_lungo|worker_nuovo)_[0-9]+" inspect.json | sort -u ### Expected behavior About 6 distinct markers of each kind in the 60 s window, or an explicit limitation saying that worker network activity is not covered. Unverified expectation: the 6.5.0 npm package ships no docs, and docs/browser-observation.md on main (not available at tag v6.5.0) says the capture includes workers and attach-window network, without saying whether worker network is included. ### Impact and scope Observed: when an app does its work in a worker, "0 network requests" from inspect-web-page can be read as "the app made no requests", while the worker did make them. Tested once, one origin, Chrome 155 on macOS, blob: dedicated workers only. Not tested: same-origin script workers, shared workers, service workers, other browsers. Severity unknown. ### REA version 6.5.0 (npm, provenance attestation verified; installed with --omit=optional --ignore-scripts) ### Runtime and platform Node v24.15.0; npm 11.12.1; macOS (architecture not recorded); Chrome 155.0.8059.80 ### Target and artifact context CDP page target (https origin) with dedicated Web Workers created from blob: URLs ### Interface CLI ### Earliest failure stage Capture or observation ### Relevant output or evidence Obtained from inspect.json of the run above (values redacted): - normalized_result.workers: 1 entry, type "worker", url `blob:https://<origin>/<uuid>`, origin `https://<origin>`, attached: true, parent_frame_id = the page target → supports "the worker was attached" - distinct markers: rea_pagina 6, rea_worker_lungo 0, rea_worker_nuovo 0 → supports "worker requests not recorded" - completeness.status "policy_filtered"; attach_limited_sections includes "network_requests"; no excluded entry for workers or network Cross-checks in the same browser (the requests did happen): - the console logged HTTP 200 for every page and worker marker - the DevTools Network panel showed the worker requests (gear icon, initiator blob:) - chrome://net-export recorded all markers: page 6/6, long-lived worker 6/6, new workers 6/6 (separate run, same snippet shortened to 6 rounds every 5 s) ### Typed outcome or recovery expected Either worker requests in normalized_result.network.requests (with the worker's target id), or a limitation/completeness entry stating that worker network activity is not observed, so that an empty result is not mistaken for "no requests". ### Analysis or suspected cause Hypothesis only, not source-derived (we did not read REA's source): Network.enable may not be sent on worker sessions, and auto-attach may not cover workers created during the window. ### Additional context - Related but different: #883 (worker source/runtime attribution), #3378 (worker inventory reported as empty), #2956 and #2166 (worker / service-worker handling under attached-scenario policies). This report is about a dedicated worker's NETWORK requests not being recorded by inspect-web-page while the worker itself is listed as attached. - A HAR exported from the DevTools Network panel also omits the worker requests even though the panel shows them, so the HAR path (inspect-web-network-capture) is blind to worker traffic too. This is Chrome behavior, not REA, but may be worth a note in the HAR docs. - Minor (docs): the 6.5.0 npm package ships no docs, and docs/browser-observation.md is not available at tag v6.5.0. - Proposal, NOT run: a shorter origin-independent snippet that should reproduce on any https origin: ```js (() => { const o = location.origin; new Worker(URL.createObjectURL(new Blob(["let n=0;const t=setInterval(()=>{n++;fetch('" + o + "/?rea_worker_long_'+n,{cache:'no-store'});if(n>=36)clearInterval(t);},10000);"], { type: 'text/javascript' }))); let i = 0; const t = setInterval(() => { i++; fetch(o + '/?rea_page_' + i, { cache: 'no-store' }); new Worker(URL.createObjectURL(new Blob(["fetch('" + o + "/?rea_worker_new_" + i + "',{cache:'no-store'}).then(()=>close())"], { type: 'text/javascript' }))); if (i >= 36) clearInterval(t); }, 10000); })(); ``` Thanks for REA: the passive design, the evidence IDs and the honest limitations field made this easy to pin down.
Author
Owner

@GautamSharma-coder commented on GitHub (Oct 16, 2026):

Confirmed from source inspection. The reporter's hypothesis is accurate:

Root Cause

  1. Event Filtering: In src/browser/CdpPageCapture.ts, events.ingest explicitly filters out any event whose sessionId !== context.sessionId. Because dedicated workers have their own target session ID in CDP, all worker events are dropped at ingestion.
  2. Domain Activation: enableObservationDomains only calls Network.enable on the page's primary session.
  3. Worker Attachment Status: In src/browser/CdpPageCaptureWorkers.ts, captureWorkers queries Target.getTargets at the browser root at the end of the window. The attached: true field reflects Chromium's internal renderer attachment state, not that REA attached to or is observing the worker.
  4. Short-lived Workers: Because Target.getTargets is queried only once at teardown and Target.setAutoAttach is not enabled, short-lived workers terminated before the end of the observation window leave no trace.
  • Phase 1 (Immediate / Epistemic Honesty): Add an explicit limitation to limitations (and update completeness/exclusions) stating that worker network activity is currently unobserved, avoiding the false inference of "0 requests". Clarify this in docs/browser-observation.md.
  • Phase 2 (Feature): Evaluate adding Target.setAutoAttach (flatten: true) on page sessions to register child worker sessions, enable Network.enable on them, and multiplex worker requests into CdpCaptureEvents.

I can put together a PR for Phase 1 right away if that's welcome, and happy to discuss the design boundaries for Phase 2 if maintainers want worker traffic in scope.

<!-- gh-comment-id:6213863428 --> @GautamSharma-coder commented on GitHub (Oct 16, 2026): Confirmed from source inspection. The reporter's hypothesis is accurate: ### Root Cause 1. **Event Filtering**: In [`src/browser/CdpPageCapture.ts`](src/browser/CdpPageCapture.ts#L76-L79), `events.ingest` explicitly filters out any event whose `sessionId !== context.sessionId`. Because dedicated workers have their own target session ID in CDP, all worker events are dropped at ingestion. 2. **Domain Activation**: [`enableObservationDomains`](src/browser/CdpPageCapture.ts#L386-L394) only calls `Network.enable` on the page's primary session. 3. **Worker Attachment Status**: In [`src/browser/CdpPageCaptureWorkers.ts`](src/browser/CdpPageCaptureWorkers.ts#L26-L71), `captureWorkers` queries `Target.getTargets` at the browser root at the end of the window. The `attached: true` field reflects Chromium's internal renderer attachment state, not that REA attached to or is observing the worker. 4. **Short-lived Workers**: Because `Target.getTargets` is queried only once at teardown and `Target.setAutoAttach` is not enabled, short-lived workers terminated before the end of the observation window leave no trace. ### Recommended Path - **Phase 1 (Immediate / Epistemic Honesty)**: Add an explicit limitation to `limitations` (and update completeness/exclusions) stating that worker network activity is currently unobserved, avoiding the false inference of "0 requests". Clarify this in `docs/browser-observation.md`. - **Phase 2 (Feature)**: Evaluate adding `Target.setAutoAttach` (`flatten: true`) on page sessions to register child worker sessions, enable `Network.enable` on them, and multiplex worker requests into `CdpCaptureEvents`. I can put together a PR for Phase 1 right away if that's welcome, and happy to discuss the design boundaries for Phase 2 if maintainers want worker traffic in scope.
Author
Owner

@matbrgz commented on GitHub (Oct 16, 2026):

Cross-referencing with sibling reports #3376 and #3378 ([Bug] Malformed worker inventories are reported as empty). In inspect-web-page, CDP worker session multiplexing is omitted, causing dedicated worker traffic to be completely discarded while reporting false zero counts.

Consolidated under Cluster I (Web Inspector Silent Drop of Malformed CDP Inventories & Workers) in tracker #4330.

<!-- gh-comment-id:6218929008 --> @matbrgz commented on GitHub (Oct 16, 2026): Cross-referencing with sibling reports #3376 and #3378 (`[Bug] Malformed worker inventories are reported as empty`). In `inspect-web-page`, CDP worker session multiplexing is omitted, causing dedicated worker traffic to be completely discarded while reporting false zero counts. Consolidated under **Cluster I (Web Inspector Silent Drop of Malformed CDP Inventories & Workers)** in tracker #4330.
Author
Owner

@morluto commented on GitHub (Oct 26, 2026):

Thank you for the reproducible worker/page comparison. Both #4456 and #4585 propose fixes for this report, with different session and verification coverage; they remain open while those approaches are coordinated. The issue stays open until the behavior is addressed. No browser run was performed in this triage.

<!-- gh-comment-id:6428612242 --> @morluto commented on GitHub (Oct 26, 2026): Thank you for the reproducible worker/page comparison. Both #4456 and #4585 propose fixes for this report, with different session and verification coverage; they remain open while those approaches are coordinated. The issue stays open until the behavior is addressed. No browser run was performed in this triage.
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#1758
No description provided.