[GH-ISSUE #571] analyze_javascript_application fails on any archive containing a directory named like a code file (e.g. npm scope @zip.js) #297

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

Originally created by @rishiteja21 on GitHub (Oct 5, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/571

Environment

  • rea-agents 3.2.1 (npm)
  • Node.js v24.20.0 (observed on Windows 11 x64; the failing code path contains no platform-specific logic, so it should reproduce on macOS/Linux as well)

Summary

analyze_javascript_application fails on any archive that contains a directory whose name ends with a code-file extension (.js, .ts, .json, …). A common real-world trigger is the npm scope @zip.js — node_modules/@zip.js/ is a directory, and it ships inside many Electron apps (e.g. anything bundling @zip.js/zip.js).

The whole analysis aborts with:

{
  "code": "artifact_operation_failed",
  "message": "Artifact is invalid or has changed. Get a fresh copy and try again.",
  "details": { "operation": "analyze_javascript_application", "reason": "format" }
}

Minimal repro

mkdir -p mini/@zip.js mini/src
echo '{"name":"mini","version":"1.0.0","main":"index.js"}' > mini/package.json
echo 'require("./@zip.js/entry.js");'                       > mini/index.js
echo 'module.exports = {};'                                 > mini/@zip.js/entry.js
echo 'console.log("app");'                                  > mini/src/main.js
npx @electron/asar pack mini mini.asar
rea analyze mini.asar --json

Verified: fails as above with 3.2.1; the only "relevant"-looking entry is the directory @zip.js.

Root cause

  1. materializeDirectoryNodes (src/application/ArtifactGraphConstruction.ts:105) materializes graph nodes for directory occurrences and sets directory.artifact_id = node.artifact_id, so directories pass the occurrence.artifact_id === null filter in expectedInventory.
  2. expectedInventory (src/application/JavaScriptArtifactFiles.ts) classifies entries purely by path suffix via relevantKind (:306): node_modules/@zip.js ends in .js → matched as "javascript" (:311). Nothing excludes directories.
  3. The read pass later calls reader.open() for that entry; AsarArtifactReader.open() rejects non-file entries with ArtifactReaderFailure("format", "ASAR entry is not a regular file"), aborting the entire analysis. (The read pass trusts expected.kind from the inventory, so a kind check only at open() cannot rescue it.)

Fix

Skip directory occurrences in expectedInventory before classification (verified: the repro asar analyzes successfully after this change to the installed dist):

// after the artifact_id/node checks
if (occurrence.entry_kind === "directory") continue;

With the fix, directory occurrences remain in the graph (they are legitimately materialized there) but are never scheduled for content reads.

Originally created by @rishiteja21 on GitHub (Oct 5, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/571 ### Environment - `rea-agents` 3.2.1 (npm) - Node.js v24.20.0 (observed on Windows 11 x64; the failing code path contains no platform-specific logic, so it should reproduce on macOS/Linux as well) ### Summary `analyze_javascript_application` fails on any archive that contains a **directory whose name ends with a code-file extension** (`.js`, `.ts`, `.json`, …). A common real-world trigger is the npm scope **`@zip.js`** — `node_modules/@zip.js/` is a directory, and it ships inside many Electron apps (e.g. anything bundling `@zip.js/zip.js`). The whole analysis aborts with: ```json { "code": "artifact_operation_failed", "message": "Artifact is invalid or has changed. Get a fresh copy and try again.", "details": { "operation": "analyze_javascript_application", "reason": "format" } } ``` ### Minimal repro ```bash mkdir -p mini/@zip.js mini/src echo '{"name":"mini","version":"1.0.0","main":"index.js"}' > mini/package.json echo 'require("./@zip.js/entry.js");' > mini/index.js echo 'module.exports = {};' > mini/@zip.js/entry.js echo 'console.log("app");' > mini/src/main.js npx @electron/asar pack mini mini.asar rea analyze mini.asar --json ``` Verified: fails as above with 3.2.1; the only "relevant"-looking entry is the directory `@zip.js`. ### Root cause 1. `materializeDirectoryNodes` (`src/application/ArtifactGraphConstruction.ts:105`) materializes graph nodes for directory occurrences and sets `directory.artifact_id = node.artifact_id`, so directories pass the `occurrence.artifact_id === null` filter in `expectedInventory`. 2. `expectedInventory` (`src/application/JavaScriptArtifactFiles.ts`) classifies entries purely by path suffix via `relevantKind` (:306): `node_modules/@zip.js` ends in `.js` → matched as `"javascript"` (:311). Nothing excludes directories. 3. The read pass later calls `reader.open()` for that entry; `AsarArtifactReader.open()` rejects non-file entries with `ArtifactReaderFailure("format", "ASAR entry is not a regular file")`, aborting the entire analysis. (The read pass trusts `expected.kind` from the inventory, so a kind check only at `open()` cannot rescue it.) ### Fix Skip directory occurrences in `expectedInventory` before classification (verified: the repro asar analyzes successfully after this change to the installed `dist`): ```ts // after the artifact_id/node checks if (occurrence.entry_kind === "directory") continue; ``` With the fix, directory occurrences remain in the graph (they are legitimately materialized there) but are never scheduled for content reads.
bsakaguchi 2026-10-15 18:23:35 +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#297
No description provided.