[GH-ISSUE #5399] [Bug] Reference-source import root errors omit required machine-readable fields #3269

Closed
opened 2026-10-31 00:38:36 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

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

Area

CLI

Observed behavior

import-reference-source returns JSON errors containing only error, category, and message when the selected root is missing or is a regular file. The required canonical code, retryable, and remediation fields are absent. Both commands exit 1 with empty stderr. With --full-output, the same incomplete object appears inside error, alongside ok: false.

An independent verifier reproduced all three cases under both Node versions below. The same command's invalid-option control returns a complete canonical error.

Reproduction

From the source checkout at the revision below, use its installed dependencies and prebuilt runtime. The verifier executed the following command sequence with isolated HOME, XDG directories, and TMPDIR; disposable paths are normalized here. Run without exit-on-error, because exit 1 is expected:

rea_probe=$(mktemp -d)
mkdir -p "$rea_probe"/home "$rea_probe"/config "$rea_probe"/data "$rea_probe"/cache "$rea_probe"/state "$rea_probe"/temp
printf x > "$rea_probe/notadir.txt"
run_rea() {
  env -i PATH="$PATH" HOME="$rea_probe/home" \
    XDG_CONFIG_HOME="$rea_probe/config" XDG_DATA_HOME="$rea_probe/data" \
    XDG_CACHE_HOME="$rea_probe/cache" XDG_STATE_HOME="$rea_probe/state" \
    TMPDIR="$rea_probe/temp" REA_LOG_LEVEL=silent \
    node scripts/rea.mjs "$@"
}
run_rea import-reference-source "$rea_probe/missing-dir" --json
printf 'exit=%s\n' "$?"
run_rea import-reference-source "$rea_probe/notadir.txt" --json
printf 'exit=%s\n' "$?"
run_rea import-reference-source "$rea_probe/missing-dir" --json --full-output
printf 'exit=%s\n' "$?"

Discriminating control, also executed under both runtimes:

run_rea import-reference-source "$rea_probe/missing-dir" --outline-depth 1 --json
printf 'exit=%s\n' "$?"

The control rejects --outline-depth without --detail summary before reading the root. It exits 1 with canonical invalid_request / invalid_input, retryable: true, and actionable remediation. No provider or external service is required.

Expected behavior

Source-derived expectation: src/contracts/errorSchemas.ts:22-35 defines the canonical projection shared by every CLI and MCP error surface, requiring code, category, nonempty message, boolean retryable, and remediation.action. Lines 81-106 permit a CLI string label around that projection. docs/error-contract.schema.json:1-40 publishes the same required fields.

Invalid-root failures should retain useful diagnostics and exit 1 while providing an appropriate complete canonical error. The full-output error member should contain the canonical projection. Generic details is optional; its absence is not this defect.

Impact and scope

P2: callers cannot validate these failures against the shared contract or read their machine-readable classification, retryability, and recovery guidance. The failure is bounded to the exercised root-admission error paths. Exit status and useful message text remain available, so callers can safely stop and display the message, although that cannot reconstruct missing metadata.

Both invalid roots and the full-output case reproduced under each tested runtime. No data loss or security boundary crossing was observed. Unsupported-host, cancellation, cleanup-failure, partial-result, and MCP paths were not reproduced.

REA version

6.7.0; source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8, using the supplied prebuilt runtime. Latest published release checked: rea-agents-6.7.0.

Runtime and platform

Node.js v26.12.0, repeated with v24.22.0; macOS. NOT_ENOUGH_INFO: architecture and exact macOS version were not recorded in the verifier's verdict. The repository's exact Node v24.18.0 pin was not used. No Hopper/Ghidra provider was involved.

Target and artifact context

Caller-selected local root paths: an absent directory and a regular text file containing the single byte x. No executable target, database, or provider is needed.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

Observed ordinary error shape, with caller-selected path text summarized:

{"error":"Import failed","category":"invalid_input","message":"<root-resolution or not-a-directory diagnostic>"}

Each affected command exits 1 with empty stderr. The full-output case returns ok: false and the same three-field object under error. The missing-root message advises checking that the directory exists and is readable; the file-root message identifies that it is not a directory.

The verifier checked the built exports corresponding to analysisCliErrorEnvelopeSchema and analysisErrorProjectionSchema. Both ordinary errors and the extracted full-output error fail both checks; removing their string label still fails the strict projection check. The control passes the labeled schema and passes the strict projection after removing the label. These results establish missing required fields, rather than merely rejection of an allowed CLI label or of the outer full-output wrapper.

Typed outcome or recovery expected

Keep exit 1 and the root diagnostic. Ordinary labeled errors should pass the labeled schema; the full-output error member should pass the canonical projection schema. Keep the same-command control passing. These are proposed restoration checks; no repair is claimed, and the contract does not establish only one acceptable error code for the invalid roots.

Analysis or suspected cause

Source-derived: src/application/ReferenceSourceImportPolicy.ts:49-83 detects the missing/non-directory roots. src/application/ReferenceSourceImport.ts:206-207 returns preparation failures. src/cli/utilityCommands.ts:357-376 adds the Import failed label to projectReferenceSourceImportError, whose return shape at src/application/ReferenceSourceImportTypes.ts:47-65 omits the required fields. The command-specific predicate at src/cli/referenceSourceImportStatus.ts:24-27 preserves failure exit status. The output wrapper receives an already incomplete payload.

Additional context

Prepared with AI assistance and independently reproduced. NOT_ENOUGH_INFO: no last-known-good version was tested.

Before submission, upstream main was fetched at e84468c0bb0476412ac0c8161f7c2ecc9a6864ca; no commits since the baseline changed the cited error schema, root policy, import projection, or utility command files. No fresh runtime replay on that later revision is claimed. Searches covered open and closed issues and PRs. PR #735 fixes exit/log classification while preserving the legacy payload; #787 / PR #789 concern unsupported Windows reader diagnostics; #3401 concerns loss of an EACCES diagnostic. They do not request the missing canonical fields for invalid roots.

Related: https://github.com/morluto/rea/issues/5397 (same canonical error contract, separate producing code path)

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5399 ### 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 CLI ### Observed behavior `import-reference-source` returns JSON errors containing only `error`, `category`, and `message` when the selected root is missing or is a regular file. The required canonical `code`, `retryable`, and `remediation` fields are absent. Both commands exit 1 with empty stderr. With `--full-output`, the same incomplete object appears inside `error`, alongside `ok: false`. An independent verifier reproduced all three cases under both Node versions below. The same command's invalid-option control returns a complete canonical error. ### Reproduction From the source checkout at the revision below, use its installed dependencies and prebuilt runtime. The verifier executed the following command sequence with isolated HOME, XDG directories, and TMPDIR; disposable paths are normalized here. Run without exit-on-error, because exit 1 is expected: ```sh rea_probe=$(mktemp -d) mkdir -p "$rea_probe"/home "$rea_probe"/config "$rea_probe"/data "$rea_probe"/cache "$rea_probe"/state "$rea_probe"/temp printf x > "$rea_probe/notadir.txt" run_rea() { env -i PATH="$PATH" HOME="$rea_probe/home" \ XDG_CONFIG_HOME="$rea_probe/config" XDG_DATA_HOME="$rea_probe/data" \ XDG_CACHE_HOME="$rea_probe/cache" XDG_STATE_HOME="$rea_probe/state" \ TMPDIR="$rea_probe/temp" REA_LOG_LEVEL=silent \ node scripts/rea.mjs "$@" } run_rea import-reference-source "$rea_probe/missing-dir" --json printf 'exit=%s\n' "$?" run_rea import-reference-source "$rea_probe/notadir.txt" --json printf 'exit=%s\n' "$?" run_rea import-reference-source "$rea_probe/missing-dir" --json --full-output printf 'exit=%s\n' "$?" ``` Discriminating control, also executed under both runtimes: ```sh run_rea import-reference-source "$rea_probe/missing-dir" --outline-depth 1 --json printf 'exit=%s\n' "$?" ``` The control rejects `--outline-depth` without `--detail summary` before reading the root. It exits 1 with canonical `invalid_request` / `invalid_input`, `retryable: true`, and actionable remediation. No provider or external service is required. ### Expected behavior Source-derived expectation: `src/contracts/errorSchemas.ts:22-35` defines the canonical projection shared by every CLI and MCP error surface, requiring `code`, `category`, nonempty `message`, boolean `retryable`, and `remediation.action`. Lines 81-106 permit a CLI string label around that projection. `docs/error-contract.schema.json:1-40` publishes the same required fields. Invalid-root failures should retain useful diagnostics and exit 1 while providing an appropriate complete canonical error. The full-output `error` member should contain the canonical projection. Generic `details` is optional; its absence is not this defect. ### Impact and scope P2: callers cannot validate these failures against the shared contract or read their machine-readable classification, retryability, and recovery guidance. The failure is bounded to the exercised root-admission error paths. Exit status and useful message text remain available, so callers can safely stop and display the message, although that cannot reconstruct missing metadata. Both invalid roots and the full-output case reproduced under each tested runtime. No data loss or security boundary crossing was observed. Unsupported-host, cancellation, cleanup-failure, partial-result, and MCP paths were not reproduced. ### REA version 6.7.0; source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`, using the supplied prebuilt runtime. Latest published release checked: `rea-agents-6.7.0`. ### Runtime and platform Node.js v26.12.0, repeated with v24.22.0; macOS. NOT_ENOUGH_INFO: architecture and exact macOS version were not recorded in the verifier's verdict. The repository's exact Node v24.18.0 pin was not used. No Hopper/Ghidra provider was involved. ### Target and artifact context Caller-selected local root paths: an absent directory and a regular text file containing the single byte `x`. No executable target, database, or provider is needed. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence Observed ordinary error shape, with caller-selected path text summarized: ```json {"error":"Import failed","category":"invalid_input","message":"<root-resolution or not-a-directory diagnostic>"} ``` Each affected command exits 1 with empty stderr. The full-output case returns `ok: false` and the same three-field object under `error`. The missing-root message advises checking that the directory exists and is readable; the file-root message identifies that it is not a directory. The verifier checked the built exports corresponding to `analysisCliErrorEnvelopeSchema` and `analysisErrorProjectionSchema`. Both ordinary errors and the extracted full-output error fail both checks; removing their string label still fails the strict projection check. The control passes the labeled schema and passes the strict projection after removing the label. These results establish missing required fields, rather than merely rejection of an allowed CLI label or of the outer full-output wrapper. ### Typed outcome or recovery expected Keep exit 1 and the root diagnostic. Ordinary labeled errors should pass the labeled schema; the full-output error member should pass the canonical projection schema. Keep the same-command control passing. These are proposed restoration checks; no repair is claimed, and the contract does not establish only one acceptable error code for the invalid roots. ### Analysis or suspected cause Source-derived: `src/application/ReferenceSourceImportPolicy.ts:49-83` detects the missing/non-directory roots. `src/application/ReferenceSourceImport.ts:206-207` returns preparation failures. `src/cli/utilityCommands.ts:357-376` adds the `Import failed` label to `projectReferenceSourceImportError`, whose return shape at `src/application/ReferenceSourceImportTypes.ts:47-65` omits the required fields. The command-specific predicate at `src/cli/referenceSourceImportStatus.ts:24-27` preserves failure exit status. The output wrapper receives an already incomplete payload. ### Additional context Prepared with AI assistance and independently reproduced. NOT_ENOUGH_INFO: no last-known-good version was tested. Before submission, upstream main was fetched at `e84468c0bb0476412ac0c8161f7c2ecc9a6864ca`; no commits since the baseline changed the cited error schema, root policy, import projection, or utility command files. No fresh runtime replay on that later revision is claimed. Searches covered open and closed issues and PRs. PR #735 fixes exit/log classification while preserving the legacy payload; #787 / PR #789 concern unsupported Windows reader diagnostics; #3401 concerns loss of an EACCES diagnostic. They do not request the missing canonical fields for invalid roots. Related: https://github.com/morluto/rea/issues/5397 (same canonical error contract, separate producing code path)
Author
Owner

@CassieFox23 commented on GitHub (Oct 21, 2026):

Thanks, coygeek, for the two-runtime check. From reading main at 01788bac8, not a run: still valid. Failures in import-reference-source go through projectReferenceSourceImportError (src/application/ReferenceSourceImportTypes.ts:47-66). It returns only category and message, plus cleanup or partial. A missing or non-directory root takes the "invalid-root" guidance at lines 21-25. The CLI wraps that at src/cli/utilityCommands.ts:369-376 as error "Import failed" and nothing more. 1629266e3c closed the same gap for the process commands (#5397) but did not touch this path. Area: CLI error contract.

🤖 Written with Claude Code (Fable 5.1, verified by Opus 5.5), posted with my OK 🦊

<!-- gh-comment-id:6321741951 --> @CassieFox23 commented on GitHub (Oct 21, 2026): Thanks, coygeek, for the two-runtime check. From reading main at 01788bac8, not a run: still valid. Failures in `import-reference-source` go through `projectReferenceSourceImportError` (`src/application/ReferenceSourceImportTypes.ts:47-66`). It returns only category and message, plus cleanup or partial. A missing or non-directory root takes the "invalid-root" guidance at lines 21-25. The CLI wraps that at src/cli/utilityCommands.ts:369-376 as error "Import failed" and nothing more. 1629266e3c closed the same gap for the process commands (#5397) but did not touch this path. Area: CLI error contract. 🤖 Written with Claude Code (Fable 5.1, verified by Opus 5.5), posted with my OK 🦊
Author
Owner

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

Resolved on main in ddb3987bb. Reference import errors use canonical AnalysisError projection and the obsolete CLI-specific error shape is removed. Executed invalid-root and other category controls validate the complete required canonical schema and retained primary diagnostic. Validation: src/application/ReferenceSourceImportTypes.test.ts — preserves primary evidence with category-specific recovery guidance; recorded execution at e1d9ebd3c. Two projection-owner cases passed; no packaged CLI or --full-output replay. CLI consumers directly return this canonical projection.

<!-- gh-comment-id:6376136632 --> @morluto commented on GitHub (Oct 23, 2026): Resolved on main in [ddb3987bb](https://github.com/morluto/rea/commit/ddb3987bb4b01f6f6dd09614938da7c2373dcfde). Reference import errors use canonical AnalysisError projection and the obsolete CLI-specific error shape is removed. Executed invalid-root and other category controls validate the complete required canonical schema and retained primary diagnostic. Validation: `src/application/ReferenceSourceImportTypes.test.ts` — preserves primary evidence with category-specific recovery guidance; recorded execution at `e1d9ebd3c`. Two projection-owner cases passed; no packaged CLI or --full-output replay. CLI consumers directly return this canonical projection.
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#3269
No description provided.