[GH-ISSUE #7416] [Bug] rea analyze classifies an existing-project/raw-target configuration conflict as execution_failure #4420

Closed
opened 2026-10-31 00:49:39 +00:00 by bsakaguchi · 0 comments
Owner

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

Before submitting

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

Area

Provider or capability discovery

Observed behavior

Selecting an existing Ghidra project with REA_GHIDRA_PROJECT_PATH and analyzing a raw 6502 image returns exit 1 with code: "execution_failure". The message and remediation.action recommend rea doctor. The explanation that this target requires fresh import appears only in details.diagnostics.reason; the result never identifies REA_GHIDRA_PROJECT_PATH, and details.settings is absent. In the same environment, scoped doctor exits 0 with healthy: true and all Ghidra scope checks healthy. The target refusal is expected; the configuration classification and recovery are the defect.

Reproduction

  1. Use an empty scratch directory. Set REA_CLI to the prepared baseline checkout's scripts/rea.mjs, put Node 24.22.1 on PATH, and set JAVA_HOME to an installed full 64-bit JDK 21. These are prerequisites; no real Ghidra installation is required. Create the fixture below. The fake executables deliberately fail if launched; this refusal occurs before engine launch.
mkdir -p home proj/app.rep ghidra/support ghidra/Ghidra/Features/Decompiler/os/mac_arm_64
cat > ghidra/Ghidra/application.properties <<'PROPERTIES'
application.version=12.1.4
application.release.name=PUBLIC
application.java.min=21
application.java.max=
PROPERTIES
cat > ghidra/support/analyzeHeadless <<'STUB'
#!/bin/sh
printf 'unexpected engine launch\n' >&2
exit 97
STUB
cp ghidra/support/analyzeHeadless ghidra/Ghidra/Features/Decompiler/os/mac_arm_64/decompile
chmod +x ghidra/support/analyzeHeadless ghidra/Ghidra/Features/Decompiler/os/mac_arm_64/decompile
: > proj/app.gpr
printf '\251\000\352' > raw.bin
  1. Run the analysis command and print its result and exit status:
HOME="$PWD/home" GHIDRA_INSTALL_DIR="$PWD/ghidra" REA_GHIDRA_PROJECT_PATH="$PWD/proj/app.gpr" node "$REA_CLI" analyze raw.bin --target-format raw-binary --architecture 6502 --entry-point 0x8000 --provider ghidra --json > analyze.json 2> analyze.stderr
analyze_status=$?
cat analyze.json
printf 'analyze exit: %s\n' "$analyze_status"

Observed output:

{"error":"Analysis failed","code":"execution_failure","category":"execution_failure","message":"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.","retryable":false,"remediation":{"action":"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed."},"details":{"provider_id":"ghidra","operation":"resolve_analysis_profile","diagnostics":{"reason":"Existing-project mode supports native ELF/PE/Mach-O programs on POSIX without fresh-import loader preparation or pinned language overrides; use fresh import for this target/host."}}}
analyze exit: 1
  1. Run the recommended provider-scoped diagnostic and print only the relevant fields:
HOME="$PWD/home" GHIDRA_INSTALL_DIR="$PWD/ghidra" REA_GHIDRA_PROJECT_PATH="$PWD/proj/app.gpr" node "$REA_CLI" doctor --provider ghidra --json > doctor.json 2> doctor.stderr
doctor_status=$?
node -e 'const d = JSON.parse(require("node:fs").readFileSync("doctor.json", "utf8")); console.log(JSON.stringify({healthy:d.healthy,environment_healthy:d.environment_healthy,ghidra_available:d.providerInspections.find(p=>p.id==="ghidra").available,ghidra_scope_checks_healthy:d.scope_checks.filter(c=>c.name.startsWith("ghidra")).every(c=>c.ok)}));'
printf 'doctor exit: %s\n' "$doctor_status"

Observed output:

{"healthy":true,"environment_healthy":false,"ghidra_available":true,"ghidra_scope_checks_healthy":true}
doctor exit: 0

This exact procedure reproduced in two fresh directories: 2/2 analyses returned the wrong error class and omitted the setting identity, and 2/2 doctor calls reported a healthy Ghidra scope. Two earlier direct CLI attempts gave the same results. Neither fake executable emitted its launch warning. The doctor's environment_healthy: false concerns unrelated missing engines/skill; the selected Ghidra scope passed.

Expected behavior

The installation guide, docs/installation.md, heading “Reuse an existing Ghidra project”, says “Windows, raw/DOS/DOL and special pinned-language import profiles require fresh import.” Keep that refusal. The recovery guide, docs/design/limits-and-recovery.md, heading “Recovery text”, requires “Preserve the configuration failure and its setting identity” and includes the setting name and next action in caller-visible recovery. Return the existing configuration-error representation, configuration_invalid with a named REA_GHIDRA_PROJECT_PATH constraint, and explain that the caller should remove that project selection to use fresh import for this target. The project setting is launch configuration; this report does not request an analysis-runtime setter for it.

Impact and scope

The observed raw-6502 CLI request consistently returns a provider execution error for a deterministic configuration incompatibility. A client cannot identify the responsible setting through details.settings, and following the recommended provider diagnostic does not expose this target-dependent conflict. No successful analysis or data loss was observed. Fresh import is the documented alternative, but real-engine recovery was not tested. Windows, DOS, DOL, pinned ELF targets and MCP were not executed in this verification.

REA version

6.8.0 (source commit a905a71e31)

Runtime and platform

Node 24.22.1; macOS 27.0.1 arm64; OpenJDK 21.0.12.1, 64-bit full JDK; fixture Ghidra layout declares 12.1.4.

Target and artifact context

Synthetic three-byte raw image (a9 00 ea), architecture 6502, entry point 0x8000; an empty project marker and matching expanded .rep directory. Installation inspection used local executable stubs; no Ghidra engine or target program ran.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

Observed evidence is the public CLI output in the reproduction: execution_failure, generic doctor recovery, missing details.settings, and a successful scoped doctor result. The executable stubs' deliberate failure was not reached. The baseline checkout stayed unchanged.

Source-only explanation (not separately executed as unit tests): src/ghidra/GhidraProvider.ts:409 requires selected existing-project configuration and an available installation; src/ghidra/GhidraProvider.ts:423 returns ProviderAdapterError for this target conflict before resolving the project. src/domain/analysisErrorProjection.ts:291 maps that type to execution_failure, and src/domain/analysisErrorPresentation.ts:435 supplies generic doctor recovery. By comparison, src/config/environment.ts:241 constructs a named ConfigurationError for existing-project/import-override conflicts, and src/domain/analysisErrorProjection.ts:288 maps that type to configuration_invalid.

The expected documentation is at docs/installation.md:1336 and docs/design/limits-and-recovery.md:269. Real Ghidra import, database reuse and a successful no-project analysis remain unverified; this report establishes the pre-engine public refusal only.

Typed outcome or recovery expected

Preserve the refusal, return configuration_invalid, and include a constraint naming REA_GHIDRA_PROJECT_PATH. The message and remediation should tell the caller to remove the project selection in the environment starting REA to take the documented fresh-import route for this target. Keep the generic installation diagnostic separate from that corrective action.

Analysis or suspected cause

Source-derived: the target-dependent existing-project guard uses ProviderAdapterError instead of the configuration-error type already used for environment-only conflicts with the same mode. The public projection therefore cannot preserve the setting identity or choose configuration recovery. Correcting generic doctor output alone would leave the wrong typed failure at the producing boundary.

Additional context

Open #2147 is related feature verification work; its maintainer has narrowed the remaining task to macOS real-provider verification after the existing-project implementation landed. Closed #6031 corrected language/compiler override-policy conflicts, a different branch and different settings. Neither covers this existing-project target-conflict result. Open and closed issues and all-state pull requests were searched; no open exact duplicate was found. The npm registry reported 6.8.0 as the latest published release during this verification.

Originally created by @coygeek on GitHub (Oct 27, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7416 ### 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 Provider or capability discovery ### Observed behavior Selecting an existing Ghidra project with `REA_GHIDRA_PROJECT_PATH` and analyzing a raw 6502 image returns exit 1 with `code: "execution_failure"`. The message and `remediation.action` recommend `rea doctor`. The explanation that this target requires fresh import appears only in `details.diagnostics.reason`; the result never identifies `REA_GHIDRA_PROJECT_PATH`, and `details.settings` is absent. In the same environment, scoped doctor exits 0 with `healthy: true` and all Ghidra scope checks healthy. The target refusal is expected; the configuration classification and recovery are the defect. ### Reproduction 1. Use an empty scratch directory. Set `REA_CLI` to the prepared baseline checkout's `scripts/rea.mjs`, put Node 24.22.1 on `PATH`, and set `JAVA_HOME` to an installed full 64-bit JDK 21. These are prerequisites; no real Ghidra installation is required. Create the fixture below. The fake executables deliberately fail if launched; this refusal occurs before engine launch. ```sh mkdir -p home proj/app.rep ghidra/support ghidra/Ghidra/Features/Decompiler/os/mac_arm_64 cat > ghidra/Ghidra/application.properties <<'PROPERTIES' application.version=12.1.4 application.release.name=PUBLIC application.java.min=21 application.java.max= PROPERTIES cat > ghidra/support/analyzeHeadless <<'STUB' #!/bin/sh printf 'unexpected engine launch\n' >&2 exit 97 STUB cp ghidra/support/analyzeHeadless ghidra/Ghidra/Features/Decompiler/os/mac_arm_64/decompile chmod +x ghidra/support/analyzeHeadless ghidra/Ghidra/Features/Decompiler/os/mac_arm_64/decompile : > proj/app.gpr printf '\251\000\352' > raw.bin ``` 2. Run the analysis command and print its result and exit status: ```sh HOME="$PWD/home" GHIDRA_INSTALL_DIR="$PWD/ghidra" REA_GHIDRA_PROJECT_PATH="$PWD/proj/app.gpr" node "$REA_CLI" analyze raw.bin --target-format raw-binary --architecture 6502 --entry-point 0x8000 --provider ghidra --json > analyze.json 2> analyze.stderr analyze_status=$? cat analyze.json printf 'analyze exit: %s\n' "$analyze_status" ``` Observed output: ```text {"error":"Analysis failed","code":"execution_failure","category":"execution_failure","message":"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.","retryable":false,"remediation":{"action":"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed."},"details":{"provider_id":"ghidra","operation":"resolve_analysis_profile","diagnostics":{"reason":"Existing-project mode supports native ELF/PE/Mach-O programs on POSIX without fresh-import loader preparation or pinned language overrides; use fresh import for this target/host."}}} analyze exit: 1 ``` 3. Run the recommended provider-scoped diagnostic and print only the relevant fields: ```sh HOME="$PWD/home" GHIDRA_INSTALL_DIR="$PWD/ghidra" REA_GHIDRA_PROJECT_PATH="$PWD/proj/app.gpr" node "$REA_CLI" doctor --provider ghidra --json > doctor.json 2> doctor.stderr doctor_status=$? node -e 'const d = JSON.parse(require("node:fs").readFileSync("doctor.json", "utf8")); console.log(JSON.stringify({healthy:d.healthy,environment_healthy:d.environment_healthy,ghidra_available:d.providerInspections.find(p=>p.id==="ghidra").available,ghidra_scope_checks_healthy:d.scope_checks.filter(c=>c.name.startsWith("ghidra")).every(c=>c.ok)}));' printf 'doctor exit: %s\n' "$doctor_status" ``` Observed output: ```text {"healthy":true,"environment_healthy":false,"ghidra_available":true,"ghidra_scope_checks_healthy":true} doctor exit: 0 ``` This exact procedure reproduced in two fresh directories: 2/2 analyses returned the wrong error class and omitted the setting identity, and 2/2 doctor calls reported a healthy Ghidra scope. Two earlier direct CLI attempts gave the same results. Neither fake executable emitted its launch warning. The doctor's `environment_healthy: false` concerns unrelated missing engines/skill; the selected Ghidra scope passed. ### Expected behavior The installation guide, `docs/installation.md`, heading “Reuse an existing Ghidra project”, says “Windows, raw/DOS/DOL and special pinned-language import profiles require fresh import.” Keep that refusal. The recovery guide, `docs/design/limits-and-recovery.md`, heading “Recovery text”, requires “Preserve the configuration failure and its setting identity” and includes the setting name and next action in caller-visible recovery. Return the existing configuration-error representation, `configuration_invalid` with a named `REA_GHIDRA_PROJECT_PATH` constraint, and explain that the caller should remove that project selection to use fresh import for this target. The project setting is launch configuration; this report does not request an analysis-runtime setter for it. ### Impact and scope The observed raw-6502 CLI request consistently returns a provider execution error for a deterministic configuration incompatibility. A client cannot identify the responsible setting through `details.settings`, and following the recommended provider diagnostic does not expose this target-dependent conflict. No successful analysis or data loss was observed. Fresh import is the documented alternative, but real-engine recovery was not tested. Windows, DOS, DOL, pinned ELF targets and MCP were not executed in this verification. ### REA version 6.8.0 (source commit a905a71e31f71457cb21fd056b234f872126974e) ### Runtime and platform Node 24.22.1; macOS 27.0.1 arm64; OpenJDK 21.0.12.1, 64-bit full JDK; fixture Ghidra layout declares 12.1.4. ### Target and artifact context Synthetic three-byte raw image (`a9 00 ea`), architecture 6502, entry point 0x8000; an empty project marker and matching expanded `.rep` directory. Installation inspection used local executable stubs; no Ghidra engine or target program ran. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence Observed evidence is the public CLI output in the reproduction: `execution_failure`, generic doctor recovery, missing `details.settings`, and a successful scoped doctor result. The executable stubs' deliberate failure was not reached. The baseline checkout stayed unchanged. Source-only explanation (not separately executed as unit tests): `src/ghidra/GhidraProvider.ts:409` requires selected existing-project configuration and an available installation; `src/ghidra/GhidraProvider.ts:423` returns `ProviderAdapterError` for this target conflict before resolving the project. `src/domain/analysisErrorProjection.ts:291` maps that type to `execution_failure`, and `src/domain/analysisErrorPresentation.ts:435` supplies generic doctor recovery. By comparison, `src/config/environment.ts:241` constructs a named `ConfigurationError` for existing-project/import-override conflicts, and `src/domain/analysisErrorProjection.ts:288` maps that type to `configuration_invalid`. The expected documentation is at `docs/installation.md:1336` and `docs/design/limits-and-recovery.md:269`. Real Ghidra import, database reuse and a successful no-project analysis remain unverified; this report establishes the pre-engine public refusal only. ### Typed outcome or recovery expected Preserve the refusal, return `configuration_invalid`, and include a constraint naming `REA_GHIDRA_PROJECT_PATH`. The message and remediation should tell the caller to remove the project selection in the environment starting REA to take the documented fresh-import route for this target. Keep the generic installation diagnostic separate from that corrective action. ### Analysis or suspected cause Source-derived: the target-dependent existing-project guard uses `ProviderAdapterError` instead of the configuration-error type already used for environment-only conflicts with the same mode. The public projection therefore cannot preserve the setting identity or choose configuration recovery. Correcting generic doctor output alone would leave the wrong typed failure at the producing boundary. ### Additional context Open [#2147](https://github.com/morluto/rea/issues/2147) is related feature verification work; its maintainer has narrowed the remaining task to macOS real-provider verification after the existing-project implementation landed. Closed [#6031](https://github.com/morluto/rea/issues/6031) corrected language/compiler override-policy conflicts, a different branch and different settings. Neither covers this existing-project target-conflict result. Open and closed issues and all-state pull requests were searched; no open exact duplicate was found. The npm registry reported 6.8.0 as the latest published release during this verification.
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#4420
No description provided.