[GH-ISSUE #1185] [Bug] NativeAOT unsupported-host rejection is reported as execution_failure with retry and doctor advice #420

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

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

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

Enabling the optional NativeAOT adapter on macOS rejects an ordinary Ghidra analysis before Ghidra starts, because the adapter is supported only on Linux. REA exposes that deliberate host rejection as execution_failure and recommends retrying once and running doctor. Repeating the request returns the same host restriction, while scoped doctor reports Ghidra healthy. The detailed reason contains the useful remedy, but the error classification, message, and remediation do not match that failed constraint.

Both tested builds returned exit 1 before provider startup. The meaningful public fields were:

{
  "code": "execution_failure",
  "category": "execution_failure",
  "message": "Analysis could not complete. Retry once; if it continues, run `rea doctor`.",
  "retryable": false,
  "remediation": {
    "action": "Analysis could not complete. Retry once; if it continues, run `rea doctor`."
  },
  "details": {
    "provider_id": "ghidra",
    "operation": "resolve_analysis_profile",
    "diagnostics": {
      "extension": "nativeaot",
      "reason": "NativeAOT recovery is verified on Linux only; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis."
    }
  }
}

The diagnostics.path field is omitted from this excerpt because it contains only the local fixture path. Both retries with the absent-path fixture returned the same error in each build. Doctor with that extension setting returned exit 0, healthy: true, and no failed Ghidra checks. Omitting the JAR variable restored the same native analysis in both builds, with exit 0, an upstream Ghidra provider profile, two procedures, and five segments.

Reproduction

Use the runtime baseline below on macOS. Build a source-owned native fixture without executing it, and copy a harmless existing JAR into scratch. This JAR is only a path fixture, not a valid NativeAOT extension; the observed host gate rejects the request before reading or loading it.

export GHIDRA_INSTALL_DIR=/path/to/ghidra_12.1.4_PUBLIC
export JAVA_HOME=/path/to/jdk-21
work_dir="$(mktemp -d /tmp/agent-work.XXXXXX)"
cat > "$work_dir/sample.c" <<'EOF'
int increment(int value) { return value + 1; }
int main(void) { return increment(41); }
EOF
clang -g -O0 "$work_dir/sample.c" -o "$work_dir/sample"
cp "$GHIDRA_INSTALL_DIR/support/LaunchSupport.jar" "$work_dir/local.jar"
REA_GHIDRA_NATIVEAOT_JAR="$work_dir/local.jar" nice -n 10 npx -y rea-agents@6.1.0 analyze "$work_dir/sample" --provider ghidra --json
REA_GHIDRA_NATIVEAOT_JAR="$work_dir/local.jar" npx -y rea-agents@6.1.0 doctor --provider ghidra --json

Repeat the analysis command, then run it with REA_GHIDRA_NATIVEAOT_JAR omitted. Repeat the REA commands using node /path/to/rea/scripts/rea.mjs in place of the package runner. Both builds were also tested with an absolute nonexistent JAR path; the same host rejection preceded artifact validation. The normal no-extension analysis control was executed on the identical compiled target in both builds.

Expected behavior

The NativeAOT guide explicitly states that other hosts are unsupported. The Boundary Contracts require unsupported capability and malformed input to remain distinct from execution failures and require recovery advice to address the actual reason. A deliberate unsupported-host check should produce an unavailable/unsupported capability outcome and direct callers to omit the optional JAR for ordinary Ghidra analysis or use the supported NativeAOT host. Retrying or changing the Ghidra installation cannot satisfy this host constraint.

Impact and scope

A deterministic unsupported capability is classified as an execution failure, and the suggested retry and healthy doctor result cannot repair the host restriction. Impact assessment: P2 (supported).

Workaround (available): The detailed reason tells callers to omit the optional JAR for ordinary native analysis, and that exact no-extension control restored analysis on both tested builds.

REA version

rea-agents@6.1.0 from npm, and main at b34bdcdb28 built locally with npm ci && npm run build:cached.

Runtime and platform

The release was rea-agents 6.1.0 and the prepared main build was commit b34bdcdb2877be394c59c9cbf70269dc1841ff78. The existing installation was official Ghidra 12.1.4 with locally built macOS arm64 natives. Java was 64-bit full Homebrew OpenJDK 21.0.12.1, Node was 24.21.0, and the host was macOS 27.0.1 arm64. The target was the source-owned arm64 Mach-O built by the inline C fixture. Analysis did not execute that target.

Target and artifact context

Thin arm64 Mach-O C executable (Ghidra provider, NativeAOT extension configured)

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

  • Expected source: docs/ghidra-nativeaot.md:8 through :13 states the supported NativeAOT host boundary; AGENTS.md:61 requires distinct unsupported outcomes and reason-specific recovery advice.
  • Failure source: The executed analysis rejection, retry, scoped-doctor result, and successful no-extension control above. src/ghidra/extensions/GhidraExtensions.ts:112 turns the intentional unsupportedReason into ProviderAdapterError, which projects to execution_failure; src/ghidra/extensions/nativeaot/NativeAotAdapter.ts:9 supplies the actual unsupported-host reason before artifact validation.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Verification covered both builds with a regular local JAR and an absent absolute JAR path; the same-target no-extension control passed on both. Source establishes the specific failed guard and why the JAR contents do not affect this host-boundary reproduction.

Typed outcome or recovery expected

Repeat the same macOS target with the optional JAR setting. It must retain the unsupported NativeAOT host reason in an unavailable/unsupported capability outcome, and its message and remediation must address that constraint. It must not tell callers to retry an unchanged host or imply that doctor can repair it. Omit the extension setting and confirm that ordinary Ghidra analysis still succeeds on the same target. Missing or malformed JAR failures on a supported NativeAOT host must remain separate from this host restriction.

Analysis or suspected cause

No response

Additional context

No response

Originally created by @coygeek on GitHub (Oct 9, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1185 ### 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 Enabling the optional NativeAOT adapter on macOS rejects an ordinary Ghidra analysis before Ghidra starts, because the adapter is supported only on Linux. REA exposes that deliberate host rejection as `execution_failure` and recommends retrying once and running doctor. Repeating the request returns the same host restriction, while scoped doctor reports Ghidra healthy. The detailed reason contains the useful remedy, but the error classification, message, and remediation do not match that failed constraint. Both tested builds returned exit 1 before provider startup. The meaningful public fields were: ```json { "code": "execution_failure", "category": "execution_failure", "message": "Analysis could not complete. Retry once; if it continues, run `rea doctor`.", "retryable": false, "remediation": { "action": "Analysis could not complete. Retry once; if it continues, run `rea doctor`." }, "details": { "provider_id": "ghidra", "operation": "resolve_analysis_profile", "diagnostics": { "extension": "nativeaot", "reason": "NativeAOT recovery is verified on Linux only; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis." } } } ``` The `diagnostics.path` field is omitted from this excerpt because it contains only the local fixture path. Both retries with the absent-path fixture returned the same error in each build. Doctor with that extension setting returned exit 0, `healthy: true`, and no failed Ghidra checks. Omitting the JAR variable restored the same native analysis in both builds, with exit 0, an upstream Ghidra provider profile, two procedures, and five segments. ### Reproduction Use the runtime baseline below on macOS. Build a source-owned native fixture without executing it, and copy a harmless existing JAR into scratch. This JAR is only a path fixture, not a valid NativeAOT extension; the observed host gate rejects the request before reading or loading it. ```sh export GHIDRA_INSTALL_DIR=/path/to/ghidra_12.1.4_PUBLIC export JAVA_HOME=/path/to/jdk-21 work_dir="$(mktemp -d /tmp/agent-work.XXXXXX)" cat > "$work_dir/sample.c" <<'EOF' int increment(int value) { return value + 1; } int main(void) { return increment(41); } EOF clang -g -O0 "$work_dir/sample.c" -o "$work_dir/sample" cp "$GHIDRA_INSTALL_DIR/support/LaunchSupport.jar" "$work_dir/local.jar" REA_GHIDRA_NATIVEAOT_JAR="$work_dir/local.jar" nice -n 10 npx -y rea-agents@6.1.0 analyze "$work_dir/sample" --provider ghidra --json REA_GHIDRA_NATIVEAOT_JAR="$work_dir/local.jar" npx -y rea-agents@6.1.0 doctor --provider ghidra --json ``` Repeat the analysis command, then run it with `REA_GHIDRA_NATIVEAOT_JAR` omitted. Repeat the REA commands using `node /path/to/rea/scripts/rea.mjs` in place of the package runner. Both builds were also tested with an absolute nonexistent JAR path; the same host rejection preceded artifact validation. The normal no-extension analysis control was executed on the identical compiled target in both builds. ### Expected behavior The NativeAOT guide explicitly states that other hosts are unsupported. The Boundary Contracts require unsupported capability and malformed input to remain distinct from execution failures and require recovery advice to address the actual reason. A deliberate unsupported-host check should produce an unavailable/unsupported capability outcome and direct callers to omit the optional JAR for ordinary Ghidra analysis or use the supported NativeAOT host. Retrying or changing the Ghidra installation cannot satisfy this host constraint. ### Impact and scope A deterministic unsupported capability is classified as an execution failure, and the suggested retry and healthy doctor result cannot repair the host restriction. Impact assessment: P2 (supported). Workaround (available): The detailed reason tells callers to omit the optional JAR for ordinary native analysis, and that exact no-extension control restored analysis on both tested builds. ### REA version `rea-agents@6.1.0` from npm, and `main` at b34bdcdb2877be394c59c9cbf70269dc1841ff78 built locally with `npm ci && npm run build:cached`. ### Runtime and platform The release was `rea-agents` 6.1.0 and the prepared main build was commit `b34bdcdb2877be394c59c9cbf70269dc1841ff78`. The existing installation was official Ghidra 12.1.4 with locally built macOS arm64 natives. Java was 64-bit full Homebrew OpenJDK 21.0.12.1, Node was 24.21.0, and the host was macOS 27.0.1 arm64. The target was the source-owned arm64 Mach-O built by the inline C fixture. Analysis did not execute that target. ### Target and artifact context Thin arm64 Mach-O C executable (Ghidra provider, NativeAOT extension configured) ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence - Expected source: `docs/ghidra-nativeaot.md:8` through `:13` states the supported NativeAOT host boundary; `AGENTS.md:61` requires distinct unsupported outcomes and reason-specific recovery advice. - Failure source: The executed analysis rejection, retry, scoped-doctor result, and successful no-extension control above. `src/ghidra/extensions/GhidraExtensions.ts:112` turns the intentional `unsupportedReason` into `ProviderAdapterError`, which projects to `execution_failure`; `src/ghidra/extensions/nativeaot/NativeAotAdapter.ts:9` supplies the actual unsupported-host reason before artifact validation. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Verification covered both builds with a regular local JAR and an absent absolute JAR path; the same-target no-extension control passed on both. Source establishes the specific failed guard and why the JAR contents do not affect this host-boundary reproduction. ### Typed outcome or recovery expected Repeat the same macOS target with the optional JAR setting. It must retain the unsupported NativeAOT host reason in an unavailable/unsupported capability outcome, and its message and remediation must address that constraint. It must not tell callers to retry an unchanged host or imply that doctor can repair it. Omit the extension setting and confirm that ordinary Ghidra analysis still succeeds on the same target. Missing or malformed JAR failures on a supported NativeAOT host must remain separate from this host restriction. ### Analysis or suspected cause _No response_ ### Additional context _No response_
bsakaguchi 2026-10-15 18:24:54 +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#420
No description provided.