[GH-ISSUE #1125] fix(android): failures recommend doctor without relevant diagnostics #398

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

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

Summary

Android package inspection with unusable Java returns execution_failure and recommends retrying, then running rea doctor. Doctor provides no Android/JADX check or selectable Android provider, so following that recovery advice does not diagnose the failed prerequisite. The actual Java failure survives only in nested diagnostics. The same advice also appears for a nonexistent class even when the Java environment works.

Steps to reproduce

  1. Supply the public Android JAR and APK identified under Runtime or environment. Install the published REA package into a disposable prefix and use an isolated home for doctor. Clear CLAUDE_CONFIG_DIR, CODEX_HOME, COPILOT_HOME, OPENCODE_CONFIG, and XDG_CONFIG_HOME for the isolated doctor run.
  2. Set REA_JADX_MCP_JAR to the absolute JAR path and JAVA_HOME to the extracted Temurin JRE's Contents/Home. Confirm that "$JAVA_HOME/bin/java" -version runs, then execute rea inspect-android-package /absolute/path/ApiDemos-debug.apk --json.
  3. Follow the printed advice by running rea doctor --json. Inspect scope_checks, checks, and providerInspections, rather than the embedded tool catalog. Also run rea doctor --provider android --json to check whether a scoped diagnostic is available.
  4. Repeat inspection with JAVA_HOME unset and PATH limited to /usr/bin:/bin on a Mac without an installed Java runtime. Invoke the REA entry script with the absolute Node executable so Node remains runnable.
  5. Repeat with JAVA_HOME unset and PATH pointing at an otherwise empty directory containing only a Node symlink. This removes Java entirely while retaining the CLI runtime.
  6. Select the full JDK fixture instead of the JRE, confirm package inspection succeeds, then run rea inspect-android-class /absolute/path/ApiDemos-debug.apk no.such.Class --json.

Expected behavior

Recovery advice should address the actual failed prerequisite and point to a workflow that can diagnose or resolve it. A JRE missing the compiler module, a nonfunctional Java stub, and an absent Java executable should expose their actionable distinction. If Android errors direct callers to doctor, that workflow should be able to inspect the relevant Android prerequisites. An absent requested class should direct the caller to correct or discover the class name rather than retrying an environment diagnostic.

Actual behavior

All three Java cases exited 1 and returned the same top-level message and remediation:

{
  "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`."
  }
}

The distinct underlying causes remained in details.diagnostics: the JRE's stderr contained Module jdk.compiler not in boot Layer; the macOS stub's stderr contained Unable to locate a Java Runtime; with no Java, reason was spawn java ENOENT.

The unscoped doctor run exited 1 with these check names:

{
  "checks": ["node", "host", "hopper", "ghidra", "ida-registration", "skill:identity"],
  "providerInspections": ["ghidra", "ida"]
}

With the full JDK, package inspection exited 0 and loaded 2,876 classes. Inspecting no.such.Class then exited 1 with the same execution_failure and doctor advice; the actual reason was details.diagnostics.reason: "Exact class not found: no.such.Class".

This is a projection of the check names and provider IDs, not the complete doctor document. No check addressed the Android JAR, Java launch, or compiler module. The scoped Android invocation exited 1 with code: "VALIDATION_ERROR".

As a control, the same inspection with the JAR environment variable unset exited 1 with capability_unavailable and the specific details.reason asking for REA_JADX_MCP_JAR. That demonstrates that missing prerequisites already have an actionable configuration path for the JAR case.

Evidence

  • Expected source: The project's boundary guidance requires recovery advice to address the failure reason and point to an available workflow; its Android guide requires a full JDK including the compiler module.
  • Failure source: Fresh CLI inspection runs under the three unusable Java environments, the working-JDK control and missing-class request, and isolated unscoped/scoped doctor runs, with the relevant JSON fields quoted above.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

The boundary contract requires actionable recovery advice. The Android prerequisites explicitly require a full JDK.

Source inspection traces these Java failures through the Android error wrapper into ProviderAdapterError. Its presentation supplies the generic doctor advice. The doctor composition includes Ghidra and IDA; core diagnostics add Hopper, but no Android check.

The same behavior remains in inspected main: the adapter-failure presentation still recommends doctor, selectable doctor providers still omit Android, and doctor provider composition and diagnostic collection are unchanged. The main runtime was not built or executed.

Restoration check

Repeat the JRE, stub, and absent-Java inspections. Verify that the error and recovery advice identify the relevant failed Java prerequisite, and that any recommended diagnostic workflow can observe it. With a working full JDK and the same public JAR/APK, package inspection should succeed. Preserve the specific missing-JAR configuration reason. The missing-class request should provide class-selection recovery while the valid package control remains successful. Fixing only MCP availability does not restore this failure-recovery contract.

Runtime or environment

  • REA release: npm rea-agents 6.0.0, tag rea-agents-6.0.0, commit 6fee42689ae6e95a0182e0d4d0f55644e73e72be, still the latest published version during verification.
  • Inspected default branch: main at 84a17d55199b1b46493aea6bf4e41029a3b200fc.
  • Runtime: Node 22.23.2, npm 12.0.2, macOS 27.0 arm64.
  • Java negative fixture: Temurin JRE 21.0.9+10 macOS arm64 tarball. java -version reported OpenJDK 21.0.9 and Temurin-21.0.9+10.
  • Java positive fixture: Temurin JDK 21.0.9+10 from the same release, asset OpenJDK21U-jdk_aarch64_mac_hotspot_21.0.9_10.tar.gz; java -version reported OpenJDK 21.0.9 and Temurin-21.0.9+10.
  • Engine: jadx-headless-mcp 0.7.1 release, asset jadx-headless-mcp-0.7.1-all.jar, SHA-256 6e5eacf500b64292bfb73c49797c1958f6ee44646e43e868039ae7feb573ff75, matching the release checksum.
  • Target: Appium ApiDemos 6.0.18 release, asset ApiDemos-debug.apk, package io.appium.android.apis, SHA-256 a9eecf37b26cd084855c530db81c2bb1b91f4c1b095a04f47aa7c20e2791f686, matching REA's fixture manifest.
  • Issue-form context: Area = Provider or capability discovery; Interface = CLI; Earliest failure stage = Setup or provider admission; Target = Android APK.

Additional context

  • Searched open and closed issues and pull requests for the behavior.
  • Removed credentials, private paths, and sensitive target data.

No exact duplicate was found. Earlier explicit-JAVA_HOME validation checks the Java executable, which does not establish a full JDK or make doctor diagnose Android. This report concerns ineffective recovery advice rather than requesting automatic installation of Java or JADX.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Android users with three unusable Java configurations, or an absent class in a working environment, receive a recovery command that cannot diagnose their failure, prolonging a blocked inspection. The nested diagnostics retain the cause, so the failure is bounded and does not establish lost analysis evidence.
  • Workaround status: available
  • Workaround basis: Callers can inspect the nested Java diagnostics and supply the documented full JDK and JAR manually. Java version inspection directly distinguishes a runnable JRE from the absent/stub cases; the JRE compiler failure identifies the full-JDK requirement. For a missing class, callers can use class search and correct the requested name.
Originally created by @coygeek on GitHub (Oct 8, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1125 ## Summary Android package inspection with unusable Java returns `execution_failure` and recommends retrying, then running `rea doctor`. Doctor provides no Android/JADX check or selectable Android provider, so following that recovery advice does not diagnose the failed prerequisite. The actual Java failure survives only in nested diagnostics. The same advice also appears for a nonexistent class even when the Java environment works. ## Steps to reproduce 1. Supply the public Android JAR and APK identified under Runtime or environment. Install the published REA package into a disposable prefix and use an isolated home for doctor. Clear `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `COPILOT_HOME`, `OPENCODE_CONFIG`, and `XDG_CONFIG_HOME` for the isolated doctor run. 2. Set `REA_JADX_MCP_JAR` to the absolute JAR path and `JAVA_HOME` to the extracted Temurin JRE's `Contents/Home`. Confirm that `"$JAVA_HOME/bin/java" -version` runs, then execute `rea inspect-android-package /absolute/path/ApiDemos-debug.apk --json`. 3. Follow the printed advice by running `rea doctor --json`. Inspect `scope_checks`, `checks`, and `providerInspections`, rather than the embedded tool catalog. Also run `rea doctor --provider android --json` to check whether a scoped diagnostic is available. 4. Repeat inspection with `JAVA_HOME` unset and PATH limited to `/usr/bin:/bin` on a Mac without an installed Java runtime. Invoke the REA entry script with the absolute Node executable so Node remains runnable. 5. Repeat with `JAVA_HOME` unset and PATH pointing at an otherwise empty directory containing only a Node symlink. This removes Java entirely while retaining the CLI runtime. 6. Select the full JDK fixture instead of the JRE, confirm package inspection succeeds, then run `rea inspect-android-class /absolute/path/ApiDemos-debug.apk no.such.Class --json`. ## Expected behavior Recovery advice should address the actual failed prerequisite and point to a workflow that can diagnose or resolve it. A JRE missing the compiler module, a nonfunctional Java stub, and an absent Java executable should expose their actionable distinction. If Android errors direct callers to doctor, that workflow should be able to inspect the relevant Android prerequisites. An absent requested class should direct the caller to correct or discover the class name rather than retrying an environment diagnostic. ## Actual behavior All three Java cases exited 1 and returned the same top-level message and remediation: ```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`." } } ``` The distinct underlying causes remained in `details.diagnostics`: the JRE's `stderr` contained `Module jdk.compiler not in boot Layer`; the macOS stub's `stderr` contained `Unable to locate a Java Runtime`; with no Java, `reason` was `spawn java ENOENT`. The unscoped doctor run exited 1 with these check names: ```json { "checks": ["node", "host", "hopper", "ghidra", "ida-registration", "skill:identity"], "providerInspections": ["ghidra", "ida"] } ``` With the full JDK, package inspection exited 0 and loaded 2,876 classes. Inspecting `no.such.Class` then exited 1 with the same `execution_failure` and doctor advice; the actual reason was `details.diagnostics.reason: "Exact class not found: no.such.Class"`. This is a projection of the check names and provider IDs, not the complete doctor document. No check addressed the Android JAR, Java launch, or compiler module. The scoped Android invocation exited 1 with `code: "VALIDATION_ERROR"`. As a control, the same inspection with the JAR environment variable unset exited 1 with `capability_unavailable` and the specific `details.reason` asking for `REA_JADX_MCP_JAR`. That demonstrates that missing prerequisites already have an actionable configuration path for the JAR case. ## Evidence - Expected source: The project's boundary guidance requires recovery advice to address the failure reason and point to an available workflow; its Android guide requires a full JDK including the compiler module. - Failure source: Fresh CLI inspection runs under the three unusable Java environments, the working-JDK control and missing-class request, and isolated unscoped/scoped doctor runs, with the relevant JSON fields quoted above. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete The [boundary contract](https://github.com/morluto/rea/blob/6fee42689ae6e95a0182e0d4d0f55644e73e72be/AGENTS.md#L59) requires actionable recovery advice. The [Android prerequisites](https://github.com/morluto/rea/blob/6fee42689ae6e95a0182e0d4d0f55644e73e72be/docs/android-analysis.md#L13-L32) explicitly require a full JDK. Source inspection traces these Java failures through [the Android error wrapper](https://github.com/morluto/rea/blob/6fee42689ae6e95a0182e0d4d0f55644e73e72be/src/android/JadxProvider.ts#L52-L82) into `ProviderAdapterError`. Its [presentation](https://github.com/morluto/rea/blob/6fee42689ae6e95a0182e0d4d0f55644e73e72be/src/domain/analysisErrorPresentation.ts#L205-L218) supplies the generic doctor advice. The [doctor composition](https://github.com/morluto/rea/blob/6fee42689ae6e95a0182e0d4d0f55644e73e72be/src/doctorRuntime.ts#L11-L19) includes Ghidra and IDA; core diagnostics add Hopper, but no Android check. The same behavior remains in inspected `main`: [the adapter-failure presentation](https://github.com/morluto/rea/blob/84a17d55199b1b46493aea6bf4e41029a3b200fc/src/domain/analysisErrorPresentation.ts#L255-L267) still recommends doctor, [selectable doctor providers](https://github.com/morluto/rea/blob/84a17d55199b1b46493aea6bf4e41029a3b200fc/src/application/Doctor.ts#L35-L36) still omit Android, and doctor provider composition and diagnostic collection are unchanged. The `main` runtime was not built or executed. ## Restoration check Repeat the JRE, stub, and absent-Java inspections. Verify that the error and recovery advice identify the relevant failed Java prerequisite, and that any recommended diagnostic workflow can observe it. With a working full JDK and the same public JAR/APK, package inspection should succeed. Preserve the specific missing-JAR configuration reason. The missing-class request should provide class-selection recovery while the valid package control remains successful. Fixing only MCP availability does not restore this failure-recovery contract. ## Runtime or environment - REA release: npm `rea-agents` 6.0.0, tag `rea-agents-6.0.0`, commit `6fee42689ae6e95a0182e0d4d0f55644e73e72be`, still the latest published version during verification. - Inspected default branch: `main` at `84a17d55199b1b46493aea6bf4e41029a3b200fc`. - Runtime: Node 22.23.2, npm 12.0.2, macOS 27.0 arm64. - Java negative fixture: [Temurin JRE 21.0.9+10 macOS arm64 tarball](https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9%2B10/OpenJDK21U-jre_aarch64_mac_hotspot_21.0.9_10.tar.gz). `java -version` reported OpenJDK 21.0.9 and Temurin-21.0.9+10. - Java positive fixture: Temurin JDK 21.0.9+10 from the same release, asset `OpenJDK21U-jdk_aarch64_mac_hotspot_21.0.9_10.tar.gz`; `java -version` reported OpenJDK 21.0.9 and Temurin-21.0.9+10. - Engine: [jadx-headless-mcp 0.7.1 release](https://github.com/1013503897/jadx-headless-mcp/releases/tag/v0.7.1), asset `jadx-headless-mcp-0.7.1-all.jar`, SHA-256 `6e5eacf500b64292bfb73c49797c1958f6ee44646e43e868039ae7feb573ff75`, matching the release checksum. - Target: [Appium ApiDemos 6.0.18 release](https://github.com/appium/android-apidemos/releases/tag/v6.0.18), asset `ApiDemos-debug.apk`, package `io.appium.android.apis`, SHA-256 `a9eecf37b26cd084855c530db81c2bb1b91f4c1b095a04f47aa7c20e2791f686`, matching REA's fixture manifest. - Issue-form context: Area = Provider or capability discovery; Interface = CLI; Earliest failure stage = Setup or provider admission; Target = Android APK. ## Additional context - [x] Searched open and closed issues and pull requests for the behavior. - [x] Removed credentials, private paths, and sensitive target data. No exact duplicate was found. Earlier explicit-JAVA_HOME validation checks the Java executable, which does not establish a full JDK or make doctor diagnose Android. This report concerns ineffective recovery advice rather than requesting automatic installation of Java or JADX. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Android users with three unusable Java configurations, or an absent class in a working environment, receive a recovery command that cannot diagnose their failure, prolonging a blocked inspection. The nested diagnostics retain the cause, so the failure is bounded and does not establish lost analysis evidence. - Workaround status: available - Workaround basis: Callers can inspect the nested Java diagnostics and supply the documented full JDK and JAR manually. Java version inspection directly distinguishes a runnable JRE from the absent/stub cases; the JRE compiler failure identifies the full-JDK requirement. For a missing class, callers can use class search and correct the requested name.
bsakaguchi 2026-10-15 18:24:45 +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#398
No description provided.