[PR #1153] [CLOSED] fix(javascript): omit self-referential bundler edges with disclosure #2687

Closed
opened 2026-10-17 21:09:04 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1153
Author: @kaoru0822-kitauji
Created: 10/9/2026
Status: ❌ Closed

Base: main ← Head: fix/javascript-self-referential-bundler-edges


📝 Commits (1)

  • c06444a fix(javascript): omit self-referential bundler edges with disclosure

📊 Changes

4 files changed (+169 additions, -18 deletions)

View changed files

📝 src/application/javascript/JavaScriptArtifactGraphBuilder.ts (+51 -14)
📝 src/application/javascript/JavaScriptArtifactGraphBundlers.ts (+19 -2)
📝 src/application/javascript/JavaScriptArtifactGraphFindings.ts (+18 -2)
➕ tests/boundary/cli/javascriptSelfReferentialBundlerEdges.test.ts (+81 -0)

📄 Description

Fixes #1146.

Problem

analyze_javascript_application lost the whole result when a webpack/Rspack chunk referenced itself:

{"code":"unreadable_output","details":{"operation":"analyze_javascript_application","reason":"Result schema rejected 1 issue at /edges/4 (custom)"}}

The application graph schema forbids self-referential edges. #1130 skipped and disclosed them only for module import relationships. Following the new AGENTS.md guidance on adjacent cases, I checked every edge composer. Two more emit self-edges, and both are reproduced on main:

  1. Bundler async chunk (JavaScriptArtifactGraphBundlers.ts). A chunk file that requests one of its own chunk ids resolves to its own chunk node. This covers single-id chunks (push([[1],{…r.e(1)…}])) and merged multi-id chunks (push([[3,4],{…r.e(4)…}])). These are the 8 edges in the issue.
  2. Static reference (JavaScriptArtifactGraphFindings.ts). A bundled module that requires its own key (push([[5],{50(e,t,r){r(50)}}])) resolves back to its own module node.

Other self-reference shapes I checked do not produce self-edges and are unchanged. They resolve to distinct nodes:

  • a worker that spawns itself;
  • a module that dynamically imports itself;
  • an HTML <script src> pointing at its own document;
  • //# sourceMappingURL= naming its own file;
  • a CommonJS file requiring itself (#1130 already covers this).

Change

  • Both composers skip an edge whose target is its own source, count it, and return the count, as addJavaScriptModuleRelationships does since #1130.
  • graphLimitations discloses each nonzero count through one helper:
    • "N bundler async-chunk request(s) resolved back to the requesting chunk itself and was/were omitted; application graph edges cannot be self-referential."
    • "N static reference(s) resolved back to the referencing module itself …"
  • The self-import message keeps its exact wording.
  • Sibling requests are kept, such as a chunk's request for another chunk id or a module's require of another module.

No schemas change.

Verification

  • New tests/boundary/cli/javascriptSelfReferentialBundlerEdges.test.ts runs through the compiled CLI. It covers single-id and merged self chunk requests (2 omitted, sibling chunk request kept) and a module self-require (1 omitted, sibling require kept). It asserts that no self-edges remain and that the limitations are disclosed. Both tests fail without the source change.
  • All 39 test files that cover the JavaScript artifact graph, bundler registrations or analyze_javascript_application: 275 passed, including javascriptSelfImportRelationships.test.ts.
  • npm run check:fast
  • The one-file reproduction from the issue, the merged-chunk variant and the module self-require each now return a complete result with the disclosure.

I also noticed that async chunk requests resolve only to chunks registered in the same file (chunkLookupKey includes the file path). Cross-file requests stay not-found. That predates this change, which doesn't alter it.

No real Hopper or Ghidra verification was run, because this change does not touch those providers.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1153 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/9/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/javascript-self-referential-bundler-edges` --- ### 📝 Commits (1) - [`c06444a`](https://github.com/morluto/rea/commit/c06444ad67309c41733271dd3bd468c22650a6f8) fix(javascript): omit self-referential bundler edges with disclosure ### 📊 Changes **4 files changed** (+169 additions, -18 deletions) <details> <summary>View changed files</summary> 📝 `src/application/javascript/JavaScriptArtifactGraphBuilder.ts` (+51 -14) 📝 `src/application/javascript/JavaScriptArtifactGraphBundlers.ts` (+19 -2) 📝 `src/application/javascript/JavaScriptArtifactGraphFindings.ts` (+18 -2) ➕ `tests/boundary/cli/javascriptSelfReferentialBundlerEdges.test.ts` (+81 -0) </details> ### 📄 Description Fixes #1146. ## Problem `analyze_javascript_application` lost the whole result when a webpack/Rspack chunk referenced itself: ```json {"code":"unreadable_output","details":{"operation":"analyze_javascript_application","reason":"Result schema rejected 1 issue at /edges/4 (custom)"}} ``` The application graph schema forbids self-referential edges. #1130 skipped and disclosed them only for module import relationships. Following the new AGENTS.md guidance on adjacent cases, I checked every edge composer. Two more emit self-edges, and both are reproduced on `main`: 1. **Bundler async chunk** (`JavaScriptArtifactGraphBundlers.ts`). A chunk file that requests one of its own chunk ids resolves to its own chunk node. This covers single-id chunks (`push([[1],{…r.e(1)…}])`) and merged multi-id chunks (`push([[3,4],{…r.e(4)…}])`). These are the 8 edges in the issue. 2. **Static reference** (`JavaScriptArtifactGraphFindings.ts`). A bundled module that requires its own key (`push([[5],{50(e,t,r){r(50)}}])`) resolves back to its own module node. Other self-reference shapes I checked do not produce self-edges and are unchanged. They resolve to distinct nodes: - a worker that spawns itself; - a module that dynamically imports itself; - an HTML `<script src>` pointing at its own document; - `//# sourceMappingURL=` naming its own file; - a CommonJS file requiring itself (#1130 already covers this). ## Change - Both composers skip an edge whose target is its own source, count it, and return the count, as `addJavaScriptModuleRelationships` does since #1130. - `graphLimitations` discloses each nonzero count through one helper: - "N bundler async-chunk request(s) resolved back to the requesting chunk itself and was/were omitted; application graph edges cannot be self-referential." - "N static reference(s) resolved back to the referencing module itself …" - The self-import message keeps its exact wording. - Sibling requests are kept, such as a chunk's request for another chunk id or a module's require of another module. No schemas change. ## Verification - New `tests/boundary/cli/javascriptSelfReferentialBundlerEdges.test.ts` runs through the compiled CLI. It covers single-id and merged self chunk requests (2 omitted, sibling chunk request kept) and a module self-require (1 omitted, sibling require kept). It asserts that no self-edges remain and that the limitations are disclosed. Both tests fail without the source change. - All 39 test files that cover the JavaScript artifact graph, bundler registrations or `analyze_javascript_application`: 275 passed, including `javascriptSelfImportRelationships.test.ts`. - `npm run check:fast` - The one-file reproduction from the issue, the merged-chunk variant and the module self-require each now return a complete result with the disclosure. I also noticed that async chunk requests resolve only to chunks registered in the **same file** (`chunkLookupKey` includes the file path). Cross-file requests stay `not-found`. That predates this change, which doesn't alter it. No real Hopper or Ghidra verification was run, because this change does not touch those providers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:09:04 +00:00
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#2687
No description provided.