[GH-ISSUE #2883] [Bug] Source-map dependency extraction silently omits optional require calls #1019

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

Originally created by @JFSAS on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2883

Observed behavior

analyze_web_bundle silently drops an unshadowed optional CommonJS call (require?.("./optional.cjs")) from a fetched source map's original_module_edges. An otherwise identical ordinary call is retained. The map is reported as included, with no dependency-omission limitation.

Reproduction

On source baseline 3e7c6302233ecbcb9b92e43ee5a60337738961bd, serve these inert fixture resources on a loopback HTTP origin:

  • /: <script src="/app.js"></script>
  • /app.js: globalThis.sourceMapFixture = true; followed by //# sourceMappingURL=/app.js.map on the next line.
  • /app.js.map:
{"version":3,"names":[],"mappings":"AAAA","sources":["src/main.cjs"],"sourcesContent":["require(\"./normal.cjs\");\nrequire?.(\"./optional.cjs\");\nfunction local(require) { require?.(\"./shadowed.cjs\"); }"]}

Open the fixture in an isolated Chrome with a loopback CDP endpoint, then run:

rea analyze-web-bundle "$CDP_ENDPOINT" "$TARGET_ID" \
  --allowed-origins "$FIXTURE_ORIGIN" --fetch-source-maps \
  --observation-ms 0 --json

The equivalent stdio MCP analyze_web_bundle request gives the same result. Inspect normalized_result.observations.source_maps.items[].original_module_edges.

Observed before the fix through both compiled CLI and stdio MCP against real Chrome: ["./normal.cjs"].

Expected literal dependency specifiers: ["./normal.cjs", "./optional.cjs"].

The local parameter named require must remain excluded. A computed argument such as require?.(selectedModule) must not invent a literal dependency. This is a static dependency candidate, not a claim that the original executes.

Cause and scope

originalDependency in src/browser/WebSourceMapFetcher.ts accepts only Babel CallExpression; optional calls are OptionalCallExpression. The downstream unbound-identifier filter independently makes the same ordinary-call assumption, so merely widening extraction would bypass lexical-shadowing checks.

The correction should keep call-site classification and the callee requiring scope validation together. Source-map bytes, digest, original text, URL resolution, ordinary calls and shadowed-call exclusion should remain unchanged.

Verification

  • macOS arm64, Node 24.18.0, npm 11.16.0, Chrome 155.0.8059.40.
  • A real loopback HTTP boundary regression fails on the base with only ./normal.cjs and passes after the fix.
  • The same fixture was run against before/after compiled builds through CLI and stdio MCP. The map's SHA-256 is unchanged: d9d6a38307044d56516840ff08aef4a583f37a188fd228ebdd21e2db69ef82c1.
  • No original CommonJS source was executed by REA. Windows/Linux and other browsers were not verified.

I searched open and closed issues/PRs for optional calls and source-map dependencies. #2599 / #2842 concern literal representation (template versus quoted strings). This report concerns the call node kind and its lexical-scope gate, including ordinary quoted specifiers; the current #2842 diff still limits extraction to CallExpression. Applying both changes may require resolving the adjacent extractor hunk.

Prepared with AI assistance; the reproduction and before/after verification above were executed locally.

Originally created by @JFSAS on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2883 ### Observed behavior `analyze_web_bundle` silently drops an unshadowed optional CommonJS call (`require?.("./optional.cjs")`) from a fetched source map's `original_module_edges`. An otherwise identical ordinary call is retained. The map is reported as `included`, with no dependency-omission limitation. ### Reproduction On source baseline `3e7c6302233ecbcb9b92e43ee5a60337738961bd`, serve these inert fixture resources on a loopback HTTP origin: - `/`: `<script src="/app.js"></script>` - `/app.js`: `globalThis.sourceMapFixture = true;` followed by `//# sourceMappingURL=/app.js.map` on the next line. - `/app.js.map`: ```json {"version":3,"names":[],"mappings":"AAAA","sources":["src/main.cjs"],"sourcesContent":["require(\"./normal.cjs\");\nrequire?.(\"./optional.cjs\");\nfunction local(require) { require?.(\"./shadowed.cjs\"); }"]} ``` Open the fixture in an isolated Chrome with a loopback CDP endpoint, then run: ```sh rea analyze-web-bundle "$CDP_ENDPOINT" "$TARGET_ID" \ --allowed-origins "$FIXTURE_ORIGIN" --fetch-source-maps \ --observation-ms 0 --json ``` The equivalent stdio MCP `analyze_web_bundle` request gives the same result. Inspect `normalized_result.observations.source_maps.items[].original_module_edges`. Observed before the fix through **both compiled CLI and stdio MCP against real Chrome**: `["./normal.cjs"]`. Expected literal dependency specifiers: `["./normal.cjs", "./optional.cjs"]`. The local parameter named `require` must remain excluded. A computed argument such as `require?.(selectedModule)` must not invent a literal dependency. This is a static dependency candidate, not a claim that the original executes. ### Cause and scope `originalDependency` in `src/browser/WebSourceMapFetcher.ts` accepts only Babel `CallExpression`; optional calls are `OptionalCallExpression`. The downstream unbound-identifier filter independently makes the same ordinary-call assumption, so merely widening extraction would bypass lexical-shadowing checks. The correction should keep call-site classification and the callee requiring scope validation together. Source-map bytes, digest, original text, URL resolution, ordinary calls and shadowed-call exclusion should remain unchanged. ### Verification - macOS arm64, Node **24.18.0**, npm **11.16.0**, Chrome **155.0.8059.40**. - A real loopback HTTP boundary regression fails on the base with only `./normal.cjs` and passes after the fix. - The same fixture was run against before/after compiled builds through CLI and stdio MCP. The map's SHA-256 is unchanged: `d9d6a38307044d56516840ff08aef4a583f37a188fd228ebdd21e2db69ef82c1`. - No original CommonJS source was executed by REA. Windows/Linux and other browsers were not verified. ### Related work and duplicate check I searched open and closed issues/PRs for optional calls and source-map dependencies. #2599 / #2842 concern **literal representation** (template versus quoted strings). This report concerns the **call node kind and its lexical-scope gate**, including ordinary quoted specifiers; the current #2842 diff still limits extraction to `CallExpression`. Applying both changes may require resolving the adjacent extractor hunk. Prepared with AI assistance; the reproduction and before/after verification above were executed locally.
bsakaguchi 2026-10-15 18:30:24 +00:00
  • closed this issue
  • added the
    bug
    label
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#1019
No description provided.