[GH-ISSUE #3915] [Bug] extensionless CommonJS JSON imports remain unresolved #1525

Closed
opened 2026-10-16 21:06:40 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 15, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3915

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

import-reference-source leaves require("./data") unresolved when its local source tree contains data.json. Node's CommonJS resolver selects that JSON file. Static proof establishes the incorrect historical dependency edge; REA was not executed. File inventory and hashes remain available.

The statically derived relationship is {"from_path":"main.cjs","to":"data","kind":"requires","resolution":"unresolved","parse_state":"parsed"}. This is not captured REA output. The same static trace retains hashed file entries for main.cjs and data.json; no syntax failure accounts for the unresolved edge.

Reproduction

These CLI steps are proposed and unexecuted. Use the source baseline under Runtime or environment, normal valid REA configuration, and an otherwise empty, stable, readable directory on macOS or Linux. The fixture contains only regular UTF-8 files, with no symlinks, .gitignore, caller exclusions, or configured reference secret patterns. An enclosing Git repository and providers are unnecessary.

mkdir source
printf 'require("./data");\n' > source/main.cjs
printf '{"value":1}\n' > source/data.json
REA_REFERENCE_SECRET_PATTERNS_JSON='[]' rea import-reference-source "$PWD/source" --json > graph.json

Inspect the main.cjs requires relationship. During the initial investigation, an equivalent disposable fixture with these exact bytes and one independent Node resolve-only control ran. It used createRequire anchored at main.cjs and .resolve for both requests. The retained results were CommonJS ./data: data.json and CommonJS ./data.json: data.json. Node never executed either fixture module. No experimental minimization or REA runtime reproduction ran; CLI output and exit status are unavailable.

Expected behavior

The relationship should be {"from_path":"main.cjs","to":"data.json","kind":"requires","resolution":"internal","parse_state":"parsed"}. The explicitly CommonJS source has an ordinary unshadowed require, and the selected target is present in the read-file lookup. Node resolution supplies the loader meaning for this exact request.

Impact and scope

A bounded historical dependency-analysis defect omits a valid local JSON edge while retaining source facts. Broader frequency is unknown. Node resolution assists manual interpretation, but no practical workaround restoring the saved graph while preserving the historical source bytes was verified.

REA version

Source baseline: rea-agents-6.5.0, revision 3b79af28e80785afce9f5998d8f03289402a1847. The initial investigation inspected the relevant main diff at cf0a38ad9774ee9acff3164052688f7a58a1c72c. Node controls used Node.js v26.10.0, Darwin arm64. REA runtime and last known good version are unknown. Linux applicability comes from source premises, not an executed control there.

Runtime and platform

REA runtime reproduction was not run. Runtime and platform details for any smaller premise checks are recorded in the version/environment field above. Real-provider versions and end-to-end output are NOT_ENOUGH_INFO because no provider was launched.

Target and artifact context

Local historical CommonJS source tree containing main.cjs and data.json; reference-source dependency graph; no provider requirement.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

  • Expected source: tests/boundary/cli/referenceSourceDirectoryImports.test.ts:67-71,82-103 uses Node resolution to establish historical CommonJS targets. tests/boundary/filesystem/referenceSourceDynamicImports.test.ts:18,27,38-49 admits exact JSON targets. The CLI contract exposes the historical graph and its relationships.
  • Failure source: the reference resolver probes "", ".ts", ".js", ".mjs", ".cjs", ".tsx", ".jsx", omitting .json. src/domain/referenceSourcePathIdentity.ts:19-32 returns only an existing candidate identity.
  • Evidence provenance: static
  • Local verification: static-proof
  • Reproduction completeness: complete

REA runtime reproduction was not run. The primary violation evidence is static; the initial investigator separately observed the Node resolve-only results above. Public reachability and admission premises follow.

The shared public source path begins at CLI registration and projection. It validates the directory-string argument, defaults to full detail, parses configuration, calls runReferenceSourceImport, passes the root and policy into importReferenceSource, and returns its graph. src/config/environment.ts:106-121 and src/config/parseConfig.ts:94-96 accept the empty secret policy shown above.

src/application/ReferenceSourceImportPolicy.ts:49-166 validates the directory and builds matchers. Defaults at src/application/ReferenceSourceImportTypes.ts:79-89 exclude neither fixture file. src/application/ReferenceSourceImport.ts:201-220 reads the tree and VCS metadata; ReferenceSourceVcsAdapter.ts:37-49 permits kind: none. The no-follow-open requirement at src/reference/ReferenceSourceReader.ts:46-51 and src/reference/ReferenceSourceReaderValidate.ts:31-32 limits this trigger to the supported hosts above. Stable regular files pass src/reference/ReferenceSourceReaderEntries.ts:192-277; unchanged descriptor contents become read entries at src/reference/ReferenceSourceReaderFile.ts:183-197,230-275.

ReferenceSourceImport.ts:239-247 builds the lookup from successfully read regular-file paths. src/domain/referenceSourceClassification.ts:46-50 classifies .cjs as JavaScript, admitted at src/domain/referenceSourceImportParsing.ts:64-65. src/domain/javascript/javascriptSourceParser.ts:40-51,65-75 selects CommonJS parsing. referenceSourceRequireBindings.ts:21-80 admits this unshadowed wrapper require: there is no module mode, loader write, with, or shadowing binding. Parsing at referenceSourceImportParsing.ts:194-211,243-258 records the literal request; lines 72-80 classify it as internal.

appendFile at ReferenceSourceImportEntries.ts:133-170 hashes files and invokes resolution. Normalization produces data; every file/index candidate misses both inventoried paths. TypeScriptEmittedSourceCandidates.ts:22-24 supplies no substitutions for .cjs. ReferenceSourceImport.ts:249-292 sorts, deduplicates, and validates the graph. src/domain/referenceSourceGraph.ts:119-125,297-323 permits this nonempty unresolved target; ReferenceSourceImport.ts:96-124 produces a partial inventory rather than rejection. The reader also records its pathname-race limitation; this report does not assert complete inventory coverage.

Typed outcome or recovery expected

Proposed, unexecuted checks: the exact fixture must yield the internal data.json edge and retain both original hashes. Changing only the statement to require("./data.json") must preserve that target. Removing data.json must leave the dependency unresolved. This restores JSON fallback without accepting missing modules and can pass independently of query-bearing ESM resolution.

Additional context

The main source inspection found that ReferenceSourceImportEntries.ts:140,182-218 still omits .json; package-main selection occurs only after an index match. Direct unshadowed require remains admitted. This differs from file/directory precedence in #3895/#3381 and package-main selection in #3896/#3383. Related application-analyzer reports #2022 and #2021 concern .cjs probing and ESM fallback in analyze-javascript-application, rather than this reference importer. These distinctions concern independent public triggers and restoration criteria.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Complete static reachability establishes a valid CommonJS JSON target reported unresolved in optional historical analysis; source inventory remains available, and no severe or universal workflow failure is established.
  • Workaround status: unverified
  • Workaround basis: Node resolution identifies the target, but no method restoring the saved graph without changing historical source bytes was tested.
Originally created by @coygeek on GitHub (Oct 15, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3915 ## 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 Evidence, artifacts, or reconstruction ## Observed behavior `import-reference-source` leaves `require("./data")` unresolved when its local source tree contains `data.json`. Node's CommonJS resolver selects that JSON file. Static proof establishes the incorrect historical dependency edge; REA was not executed. File inventory and hashes remain available. The statically derived relationship is `{"from_path":"main.cjs","to":"data","kind":"requires","resolution":"unresolved","parse_state":"parsed"}`. This is not captured REA output. The same static trace retains hashed file entries for `main.cjs` and `data.json`; no syntax failure accounts for the unresolved edge. ## Reproduction These CLI steps are proposed and unexecuted. Use the source baseline under Runtime or environment, normal valid REA configuration, and an otherwise empty, stable, readable directory on macOS or Linux. The fixture contains only regular UTF-8 files, with no symlinks, `.gitignore`, caller exclusions, or configured reference secret patterns. An enclosing Git repository and providers are unnecessary. ```sh mkdir source printf 'require("./data");\n' > source/main.cjs printf '{"value":1}\n' > source/data.json REA_REFERENCE_SECRET_PATTERNS_JSON='[]' rea import-reference-source "$PWD/source" --json > graph.json ``` Inspect the `main.cjs` requires relationship. During the initial investigation, an equivalent disposable fixture with these exact bytes and one independent Node resolve-only control ran. It used `createRequire` anchored at `main.cjs` and `.resolve` for both requests. The retained results were `CommonJS ./data: data.json` and `CommonJS ./data.json: data.json`. Node never executed either fixture module. No experimental minimization or REA runtime reproduction ran; CLI output and exit status are unavailable. ## Expected behavior The relationship should be `{"from_path":"main.cjs","to":"data.json","kind":"requires","resolution":"internal","parse_state":"parsed"}`. The explicitly CommonJS source has an ordinary unshadowed `require`, and the selected target is present in the read-file lookup. Node resolution supplies the loader meaning for this exact request. ## Impact and scope A bounded historical dependency-analysis defect omits a valid local JSON edge while retaining source facts. Broader frequency is unknown. Node resolution assists manual interpretation, but no practical workaround restoring the saved graph while preserving the historical source bytes was verified. ## REA version Source baseline: `rea-agents-6.5.0`, revision `3b79af28e80785afce9f5998d8f03289402a1847`. The initial investigation inspected the relevant main diff at `cf0a38ad9774ee9acff3164052688f7a58a1c72c`. Node controls used Node.js `v26.10.0`, Darwin arm64. REA runtime and last known good version are unknown. Linux applicability comes from source premises, not an executed control there. ## Runtime and platform REA runtime reproduction was not run. Runtime and platform details for any smaller premise checks are recorded in the version/environment field above. Real-provider versions and end-to-end output are NOT_ENOUGH_INFO because no provider was launched. ## Target and artifact context Local historical CommonJS source tree containing `main.cjs` and `data.json`; reference-source dependency graph; no provider requirement. ## Interface CLI ## Earliest failure stage Native analysis or reconstruction ## Relevant output or evidence - Expected source: `tests/boundary/cli/referenceSourceDirectoryImports.test.ts:67-71,82-103` uses Node resolution to establish historical CommonJS targets. `tests/boundary/filesystem/referenceSourceDynamicImports.test.ts:18,27,38-49` admits exact JSON targets. The [CLI contract](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/docs/cli.md#L227-L257) exposes the historical graph and its relationships. - Failure source: the [reference resolver](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/application/ReferenceSourceImportEntries.ts#L97-L170) probes `"", ".ts", ".js", ".mjs", ".cjs", ".tsx", ".jsx"`, omitting `.json`. `src/domain/referenceSourcePathIdentity.ts:19-32` returns only an existing candidate identity. - Evidence provenance: static - Local verification: static-proof - Reproduction completeness: complete REA runtime reproduction was not run. The primary violation evidence is static; the initial investigator separately observed the Node resolve-only results above. Public reachability and admission premises follow. The shared public source path begins at [CLI registration and projection](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/cli/utilityCommands.ts#L233-L395). It validates the directory-string argument, defaults to full detail, parses configuration, calls `runReferenceSourceImport`, passes the root and policy into `importReferenceSource`, and returns its graph. `src/config/environment.ts:106-121` and `src/config/parseConfig.ts:94-96` accept the empty secret policy shown above. `src/application/ReferenceSourceImportPolicy.ts:49-166` validates the directory and builds matchers. Defaults at `src/application/ReferenceSourceImportTypes.ts:79-89` exclude neither fixture file. `src/application/ReferenceSourceImport.ts:201-220` reads the tree and VCS metadata; `ReferenceSourceVcsAdapter.ts:37-49` permits `kind: none`. The no-follow-open requirement at `src/reference/ReferenceSourceReader.ts:46-51` and `src/reference/ReferenceSourceReaderValidate.ts:31-32` limits this trigger to the supported hosts above. Stable regular files pass `src/reference/ReferenceSourceReaderEntries.ts:192-277`; unchanged descriptor contents become read entries at `src/reference/ReferenceSourceReaderFile.ts:183-197,230-275`. `ReferenceSourceImport.ts:239-247` builds the lookup from successfully read regular-file paths. `src/domain/referenceSourceClassification.ts:46-50` classifies `.cjs` as JavaScript, admitted at `src/domain/referenceSourceImportParsing.ts:64-65`. `src/domain/javascript/javascriptSourceParser.ts:40-51,65-75` selects CommonJS parsing. `referenceSourceRequireBindings.ts:21-80` admits this unshadowed wrapper `require`: there is no module mode, loader write, `with`, or shadowing binding. Parsing at `referenceSourceImportParsing.ts:194-211,243-258` records the literal request; lines 72-80 classify it as internal. `appendFile` at `ReferenceSourceImportEntries.ts:133-170` hashes files and invokes resolution. Normalization produces `data`; every file/index candidate misses both inventoried paths. `TypeScriptEmittedSourceCandidates.ts:22-24` supplies no substitutions for `.cjs`. `ReferenceSourceImport.ts:249-292` sorts, deduplicates, and validates the graph. `src/domain/referenceSourceGraph.ts:119-125,297-323` permits this nonempty unresolved target; `ReferenceSourceImport.ts:96-124` produces a partial inventory rather than rejection. The reader also records its pathname-race limitation; this report does not assert complete inventory coverage. ## Typed outcome or recovery expected Proposed, unexecuted checks: the exact fixture must yield the internal `data.json` edge and retain both original hashes. Changing only the statement to `require("./data.json")` must preserve that target. Removing `data.json` must leave the dependency unresolved. This restores JSON fallback without accepting missing modules and can pass independently of query-bearing ESM resolution. ## Additional context The main source inspection found that `ReferenceSourceImportEntries.ts:140,182-218` still omits `.json`; package-main selection occurs only after an index match. Direct unshadowed `require` remains admitted. This differs from file/directory precedence in #3895/#3381 and package-main selection in #3896/#3383. Related application-analyzer reports #2022 and #2021 concern `.cjs` probing and ESM fallback in `analyze-javascript-application`, rather than this reference importer. These distinctions concern independent public triggers and restoration criteria. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Complete static reachability establishes a valid CommonJS JSON target reported unresolved in optional historical analysis; source inventory remains available, and no severe or universal workflow failure is established. - Workaround status: unverified - Workaround basis: Node resolution identifies the target, but no method restoring the saved graph without changing historical source bytes was tested.
Author
Owner

@yankikucuk commented on GitHub (Oct 15, 2026):

Looked at this while working on the neighbouring reference-source reports (#3916, #3932). Open PR #4017 ("honor Node require extension order") replaces the single suffix list with Node's CommonJS probe order for requires edges, including .json, and its fixtures resolve a data.json target, so require("./data") → data.json should close with that PR rather than a second change to the same resolver. Not claiming this one.

<!-- gh-comment-id:6189942900 --> @yankikucuk commented on GitHub (Oct 15, 2026): Looked at this while working on the neighbouring reference-source reports (#3916, #3932). Open PR #4017 ("honor Node require extension order") replaces the single suffix list with Node's CommonJS probe order for `requires` edges, including `.json`, and its fixtures resolve a `data.json` target, so `require("./data")` → `data.json` should close with that PR rather than a second change to the same resolver. Not claiming this one.
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#1525
No description provided.