[GH-ISSUE #5971] [Bug] Android CLI schema errors omit rejected fields and constraints #3641

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

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

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

Android CLI requests with explicitly empty required strings return invalid_request without details.issues. The application schema identifies the invalid field and its minimum length, but that metadata is absent from the resulting error. The remediation tells the caller to correct the listed fields even though none are listed.

This reproduced through the built CLI for all five static Android command families. Every invocation exited 1 with empty stderr. No APK, Android device, JADX or Java process was needed because validation failed before target access.

Reproduction

Run the documented entry in a built checkout, or replace node scripts/rea.mjs with the installed rea command:

node scripts/rea.mjs inspect-android-class /nonexistent/example.apk '' --format json
node scripts/rea.mjs inspect-android-package '' --format json
node scripts/rea.mjs inspect-android-method /nonexistent/example.apk example.Class '' --format json
node scripts/rea.mjs trace-android-references /nonexistent/example.apk example.Class --method-name '' --format json
node scripts/rea.mjs search-android-classes '' query --format json

All five commands were executed once and omitted details. As a control, supplying example.Class instead of the empty class name advanced to target_unavailable for the nonexistent APK. This establishes that the empty selector fails the earlier input-validation boundary.

Expected behavior

Preserve the safe field issue when turning schema validation failure into AnalysisInputError. For an empty class name, return a correction entry such as:

{"path":["class_name"],"reason":"out_of_range","minimum":1}

The standard helper retains schema issues, and the sibling operation/input admission path removes the internal input wrapper from issue paths. The standard error projection exposes these issues to callers. Keep the correct rejection and nonzero exit status.

Impact and scope

P3: missing correction diagnostics for rejected inputs. Error classification and exit status are correct, but callers cannot identify the rejected field or constraint from the error alone. Inspecting usage and the named input schema, then supplying nonempty required values, is a workaround. No incorrect success, data loss or failure of valid Android analysis was observed.

Executed scope is the five CLI cases above. MCP input admission and real provider analysis were not exercised for this finding.

REA version

rea-agents 6.7.0; source revision 5241597594.

Runtime and platform

Node.js v24.18.0; macOS 27.0.1 arm64. Built CLI runtime and locked dependencies from the source checkout. No external analysis engine was launched.

Target and artifact context

An explicitly empty APK path or class/method selector. /nonexistent/example.apk is a deliberately absent path; schema rejection occurs before REA tries to open it.

Interface

CLI

Earliest failure stage

Request parsing or validation

Relevant output or evidence

Actual stdout for the empty class-name command; exit 1, empty stderr:

{
  "code": "invalid_request",
  "category": "invalid_input",
  "message": "Analysis input is invalid. Check the arguments and try again.",
  "retryable": false,
  "remediation": {
    "action": "Read the declared input schema or CLI usage for inspect_android_class; if using MCP and the catalog may be stale, call tools/list. Correct the listed fields, then retry. Do not repeat the unchanged call."
  },
  "recovery": {"kind":"inspect_input_contract","operation":"inspect_android_class"}
}

An additional direct execution of the built named schema and projectInputIssues for the same input returned:

{
  "rawIssues": [{"origin":"string","code":"too_small","minimum":1,"inclusive":true,"path":["input","class_name"],"message":"Too small: expected string to have >=1 characters"}],
  "projectedIssues": [{"path":["input","class_name"],"reason":"out_of_range","minimum":1}]
}

This shows that the schema and projector have the missing information. The public CLI output demonstrates its loss. Removing the internal input prefix follows the existing sibling implementation; no fix was executed.

Typed outcome or recovery expected

Keep invalid_request, invalid_input, exit 1 and inspect_input_contract recovery. Add nonempty details.issues with the rejected argument's path, reason and applicable bound. Do not echo raw rejected values.

Analysis or suspected cause

The CLI string argument declarations accept empty strings, while the named Android schemas require nonempty path/class/method values. AndroidAnalysisService.execute catches the application-schema failure and constructs AnalysisInputError with only its cause. The constructor defaults the separate issue list to empty, so the public projection omits details.

The Zod error remains available as the internal cause; its safe correction metadata is lost at construction of the public typed error. This is source-derived diagnosis of the executed output.

Additional context

#3865 and closed #2180 describe the same omission in separate Electron/browser/Inspector handlers. Preserving issues in those handlers does not repair this Android admission branch. Closed #3927 concerns post-provider cancellation classification rather than initial input diagnostics.

Fetched upstream main 25e1a24a3e; the Android service, named schemas and CLI lines remain unchanged. That newer revision was not executed.

Originally created by @coygeek on GitHub (Oct 21, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5971 ### 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 Android CLI requests with explicitly empty required strings return `invalid_request` without `details.issues`. The application schema identifies the invalid field and its minimum length, but that metadata is absent from the resulting error. The remediation tells the caller to correct the listed fields even though none are listed. This reproduced through the built CLI for all five static Android command families. Every invocation exited 1 with empty stderr. No APK, Android device, JADX or Java process was needed because validation failed before target access. ### Reproduction Run the documented entry in a built checkout, or replace `node scripts/rea.mjs` with the installed `rea` command: ```sh node scripts/rea.mjs inspect-android-class /nonexistent/example.apk '' --format json node scripts/rea.mjs inspect-android-package '' --format json node scripts/rea.mjs inspect-android-method /nonexistent/example.apk example.Class '' --format json node scripts/rea.mjs trace-android-references /nonexistent/example.apk example.Class --method-name '' --format json node scripts/rea.mjs search-android-classes '' query --format json ``` All five commands were executed once and omitted `details`. As a control, supplying `example.Class` instead of the empty class name advanced to `target_unavailable` for the nonexistent APK. This establishes that the empty selector fails the earlier input-validation boundary. ### Expected behavior Preserve the safe field issue when turning schema validation failure into `AnalysisInputError`. For an empty class name, return a correction entry such as: ```json {"path":["class_name"],"reason":"out_of_range","minimum":1} ``` The [standard helper](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/domain/inputIssueProjection.ts#L7-L25) retains schema issues, and the [sibling operation/input admission path](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/application/ProviderOperationExecution.ts#L61-L74) removes the internal `input` wrapper from issue paths. The [standard error projection](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/domain/analysisErrorProjection.ts#L333-L346) exposes these issues to callers. Keep the correct rejection and nonzero exit status. ### Impact and scope P3: missing correction diagnostics for rejected inputs. Error classification and exit status are correct, but callers cannot identify the rejected field or constraint from the error alone. Inspecting usage and the named input schema, then supplying nonempty required values, is a workaround. No incorrect success, data loss or failure of valid Android analysis was observed. Executed scope is the five CLI cases above. MCP input admission and real provider analysis were not exercised for this finding. ### REA version rea-agents 6.7.0; source revision 52415975942a4b9c53a817915b313ccc404f280e. ### Runtime and platform Node.js v24.18.0; macOS 27.0.1 arm64. Built CLI runtime and locked dependencies from the source checkout. No external analysis engine was launched. ### Target and artifact context An explicitly empty APK path or class/method selector. `/nonexistent/example.apk` is a deliberately absent path; schema rejection occurs before REA tries to open it. ### Interface CLI ### Earliest failure stage Request parsing or validation ### Relevant output or evidence Actual stdout for the empty class-name command; exit 1, empty stderr: ```json { "code": "invalid_request", "category": "invalid_input", "message": "Analysis input is invalid. Check the arguments and try again.", "retryable": false, "remediation": { "action": "Read the declared input schema or CLI usage for inspect_android_class; if using MCP and the catalog may be stale, call tools/list. Correct the listed fields, then retry. Do not repeat the unchanged call." }, "recovery": {"kind":"inspect_input_contract","operation":"inspect_android_class"} } ``` An additional direct execution of the built named schema and `projectInputIssues` for the same input returned: ```json { "rawIssues": [{"origin":"string","code":"too_small","minimum":1,"inclusive":true,"path":["input","class_name"],"message":"Too small: expected string to have >=1 characters"}], "projectedIssues": [{"path":["input","class_name"],"reason":"out_of_range","minimum":1}] } ``` This shows that the schema and projector have the missing information. The public CLI output demonstrates its loss. Removing the internal `input` prefix follows the existing sibling implementation; no fix was executed. ### Typed outcome or recovery expected Keep `invalid_request`, `invalid_input`, exit 1 and `inspect_input_contract` recovery. Add nonempty `details.issues` with the rejected argument's path, reason and applicable bound. Do not echo raw rejected values. ### Analysis or suspected cause The [CLI string argument declarations](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/cli/androidCommands.ts#L32-L33) accept empty strings, while the [named Android schemas](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/domain/android/androidAnalysis.ts#L5-L27) require nonempty path/class/method values. [AndroidAnalysisService.execute](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/application/android/AndroidAnalysisService.ts#L28-L39) catches the application-schema failure and constructs `AnalysisInputError` with only its cause. The [constructor](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/domain/analysisErrorCore.ts#L64-L76) defaults the separate issue list to empty, so the public projection omits `details`. The Zod error remains available as the internal cause; its safe correction metadata is lost at construction of the public typed error. This is source-derived diagnosis of the executed output. ### Additional context #3865 and closed #2180 describe the same omission in separate Electron/browser/Inspector handlers. Preserving issues in those handlers does not repair this Android admission branch. Closed #3927 concerns post-provider cancellation classification rather than initial input diagnostics. Fetched upstream main 25e1a24a3ed3671a0148757555f18d16c29d936a; the Android service, named schemas and CLI lines remain unchanged. That newer revision was not executed.
Author
Owner

@Ethereal49 commented on GitHub (Oct 22, 2026):

I can take this. I will reproduce one empty Android selector through the shared CLI/MCP admission path, preserve the projected field issues when constructing AnalysisInputError, and add a focused regression that keeps invalid_request, exit 1, and does not echo raw input values. MCP and real-provider coverage that is not exercised will be reported as NOT_RUN.

<!-- gh-comment-id:6337972409 --> @Ethereal49 commented on GitHub (Oct 22, 2026): I can take this. I will reproduce one empty Android selector through the shared CLI/MCP admission path, preserve the projected field issues when constructing `AnalysisInputError`, and add a focused regression that keeps `invalid_request`, exit 1, and does not echo raw input values. MCP and real-provider coverage that is not exercised will be reported as NOT_RUN.
Author
Owner

@coygeek commented on GitHub (Oct 24, 2026):

Source inspection of d87e73f2db50be72d33a4b3c7199af35518b441c shows the shared Android admission path now preserves projected field issues and removes the internal input prefix. The empty-class regression and empty path/class/method assertions check invalid_request, caller field paths and minimum: 1.

I also replayed all five reported CLI invocations. Each now exits 1 with empty stderr and invalid_request details naming the rejected caller field and its minimum length. The nonempty-selector control still advances to target_unavailable.

I ran the cited regression files on this revision; all passed as part of the focused 28-file, 603-test run. Provider-facing checks here use controlled fixtures; this does not claim a run with the real analysis engine. Closing as completed on main.

<!-- gh-comment-id:6380645827 --> @coygeek commented on GitHub (Oct 24, 2026): Source inspection of `d87e73f2db50be72d33a4b3c7199af35518b441c` shows the shared Android admission path now [preserves projected field issues](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/application/android/AndroidAnalysisService.ts#L35-L44) and [removes the internal input prefix](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/domain/inputIssueProjection.ts#L29-L44). The [empty-class regression](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/application/android/AndroidAnalysisService.test.ts#L6-L29) and [empty path/class/method assertions](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/boundary/process/androidAnalysisMcp.test.ts#L27-L55) check `invalid_request`, caller field paths and `minimum: 1`. I also replayed all five reported CLI invocations. Each now exits 1 with empty stderr and `invalid_request` details naming the rejected caller field and its minimum length. The nonempty-selector control still advances to `target_unavailable`. I ran the cited regression files on this revision; all passed as part of the focused 28-file, 603-test run. Provider-facing checks here use controlled fixtures; this does not claim a run with the real analysis engine. Closing as completed on main.
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#3641
No description provided.