[GH-ISSUE #5691] [Bug] Objdump launch failures recommend changing the target or fixing read access #3444

Closed
opened 2026-10-31 00:40:32 +00:00 by bsakaguchi · 3 comments
Owner

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

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

Both list-objdump-architectures and inspect-with-objdump misidentify failures to launch the executable selected by REA_OBJDUMP_COMMAND:

  • An absent executable returns capability_unavailable and tells callers to choose another analysis or target, even for the target-free architecture listing.
  • A directory or a readable mode-0644 shell file returns access_denied, identifies the executable path, but labels the boundary filesystem-read and recommends retrying with a readable local file. The artifact is already readable; execution permission is the failing boundary.

An independent verifier observed all six failures at the baseline. I replayed all six on current main with the same outcomes. Both mode-0755 executable controls succeeded in each run.

Reproduction

From the built source checkout with locked dependencies installed, run this POSIX shell fixture:

work_dir="$(mktemp -d)"
mkdir -p "$work_dir/home" "$work_dir/cfg" "$work_dir/data" \
  "$work_dir/cache" "$work_dir/state" "$work_dir/tmp" "$work_dir/bin"
printf 'readable artifact\n' > "$work_dir/artifact"
mkdir "$work_dir/bin/directory-command"
printf '#!/bin/sh\nprintf "BFD test target\\n"\n' > "$work_dir/bin/non-executable"
chmod 644 "$work_dir/bin/non-executable"
printf '#!/bin/sh\nprintf "BFD test target\\n"\n' > "$work_dir/bin/working-command"
chmod 755 "$work_dir/bin/working-command"

run_rea() {
  selected_command="$1"
  shift
  env -i PATH="$PATH" HOME="$work_dir/home" \
    XDG_CONFIG_HOME="$work_dir/cfg" XDG_DATA_HOME="$work_dir/data" \
    XDG_CACHE_HOME="$work_dir/cache" XDG_STATE_HOME="$work_dir/state" \
    TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \
    REA_OBJDUMP_COMMAND="$selected_command" \
    node scripts/rea.mjs "$@" --json
}

for variant in missing-command directory-command non-executable working-command; do
  run_rea "$work_dir/bin/$variant" list-objdump-architectures
  printf 'architecture-list exit: %s\n' "$?"
  run_rea "$work_dir/bin/$variant" inspect-with-objdump "$work_dir/artifact" file_headers
  printf 'artifact-inspection exit: %s\n' "$?"
done

Each variant ran once through each command on current main. The missing, directory and non-executable cases each exit 1. Both working-command calls exit 0. The shell fixture tests launch and output capture only; no real GNU objdump installation is needed.

Expected behavior

Identify inability to launch the selected provider and offer recovery through an executable GNU objdump selection, including REA_OBJDUMP_COMMAND where applicable. Preserve the host failure distinction and selected command identity. A target-free operation cannot recover by changing targets; a readable non-executable file does not have a read-access failure.

The provider guide documents caller-supplied GNU objdump and pathless architecture listing. The lifecycle contract separates target admission from provider readiness. No particular replacement sentence or implementation is required.

Impact and scope

P2: bounded recovery misdirection for invalid provider selections. Six CLI failures reproduced on current main. Selecting an executable provider restored both fixture controls. The architecture listing has no artifact to change. No evidence corruption, downstream retry loop, or security boundary crossing was observed. Real GNU objdump analysis, MCP replay, Windows and Linux were not tested.

REA version

rea-agents 6.7.0. Independently verified baseline 9d8e7803326a382cbbb3ffdb900f5e93e5442d68; rebuilt and replayed on origin/main at 7dd6941393c852a3324cf01c2bd79a9dcff43728. Latest published release is rea-agents-6.7.0.

Runtime and platform

Node.js v26.12.0; macOS 27.0.1; arm64.

Target and artifact context

An inert readable text artifact for inspection; no artifact for architecture listing. Selected commands are an absent path, a directory, a readable non-executable shell file, and an otherwise equivalent executable shell-file control. HOME, XDG directories and temporary state are isolated.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

Observed missing-command error from both commands, exit 1:

{"code":"capability_unavailable","category":"unsupported_provider","message":"This analysis is unavailable for the current target. Choose another analysis or target.","retryable":false,"remediation":{"action":"This analysis is unavailable for the current target. Choose another analysis or target."},"details":{"provider_id":"objdump","operation":"inspect_with_objdump","reason":"Unable to run configured command (ENOENT)"}}

Directory and mode-0644 cases each return access_denied, category unavailable, retryable: false, details.system_code: EACCES, and details.boundary: filesystem-read. The executable path remains in details.path. Their exact message and remediation are:

Host filesystem permissions denied read access to the selected path.
Check the current process's read access to the selected path. Retry with a readable local file.

Both executable controls preserve stdout BFD test target\n and completion_status: complete. Architecture listing returns subject: null; artifact inspection retains its digest and reports artifact_changed: false. Evidence provenance: observed; local verification: independently reproduced, then replayed on main.

Typed outcome or recovery expected

Keep all six invalid selections as failures while identifying the provider-launch boundary, selected executable and host error. Missing-command recovery should concern provider selection; EACCES recovery should concern executable selection or execution permission. Preserve both success controls and separate diagnostics for missing, invalid or unreadable artifacts. Those artifact regression checks are proposed, not executed here.

Analysis or suspected cause

Source-derived reasoning: ReverseEngineeringService.ts maps early launch EACCES to AnalysisAccessDeniedError for the command, and ENOENT to a generic capability refusal without provider-specific recovery. src/domain/analysisErrorPresentation.ts:124-128,249-250,373-377 supplies the read/target advice; src/domain/analysisErrorProjection.ts:317-322 supplies filesystem-read. The selected command comes from src/composition/reverseEngineering.ts:18-24.

Additional context

Prepared with AI assistance. No fix or restoration was tested; the last known good version is unknown.

Related #5401 concerns missing/directory artifact inputs before provider launch. This report selects invalid provider commands and also reproduces without an artifact, so it requires a separate recovery signal. #5177 concerns Apktool launcher permissions; #1952 concerns ADB advice; #3347 and #3337 concern Apktool timeout and process cleanup. Their provider-specific scopes do not cover this objdump failure. Open PR #1960 retains the generic ENOENT fallback and leaves this EACCES mapping unchanged.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5691 ### 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 Both `list-objdump-architectures` and `inspect-with-objdump` misidentify failures to launch the executable selected by `REA_OBJDUMP_COMMAND`: - An absent executable returns `capability_unavailable` and tells callers to choose another analysis or target, even for the target-free architecture listing. - A directory or a readable mode-0644 shell file returns `access_denied`, identifies the executable path, but labels the boundary `filesystem-read` and recommends retrying with a readable local file. The artifact is already readable; execution permission is the failing boundary. An independent verifier observed all six failures at the baseline. I replayed all six on current main with the same outcomes. Both mode-0755 executable controls succeeded in each run. ### Reproduction From the built source checkout with locked dependencies installed, run this POSIX shell fixture: ```sh work_dir="$(mktemp -d)" mkdir -p "$work_dir/home" "$work_dir/cfg" "$work_dir/data" \ "$work_dir/cache" "$work_dir/state" "$work_dir/tmp" "$work_dir/bin" printf 'readable artifact\n' > "$work_dir/artifact" mkdir "$work_dir/bin/directory-command" printf '#!/bin/sh\nprintf "BFD test target\\n"\n' > "$work_dir/bin/non-executable" chmod 644 "$work_dir/bin/non-executable" printf '#!/bin/sh\nprintf "BFD test target\\n"\n' > "$work_dir/bin/working-command" chmod 755 "$work_dir/bin/working-command" run_rea() { selected_command="$1" shift env -i PATH="$PATH" HOME="$work_dir/home" \ XDG_CONFIG_HOME="$work_dir/cfg" XDG_DATA_HOME="$work_dir/data" \ XDG_CACHE_HOME="$work_dir/cache" XDG_STATE_HOME="$work_dir/state" \ TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \ REA_OBJDUMP_COMMAND="$selected_command" \ node scripts/rea.mjs "$@" --json } for variant in missing-command directory-command non-executable working-command; do run_rea "$work_dir/bin/$variant" list-objdump-architectures printf 'architecture-list exit: %s\n' "$?" run_rea "$work_dir/bin/$variant" inspect-with-objdump "$work_dir/artifact" file_headers printf 'artifact-inspection exit: %s\n' "$?" done ``` Each variant ran once through each command on current main. The missing, directory and non-executable cases each exit 1. Both working-command calls exit 0. The shell fixture tests launch and output capture only; no real GNU objdump installation is needed. ### Expected behavior Identify inability to launch the selected provider and offer recovery through an executable GNU objdump selection, including `REA_OBJDUMP_COMMAND` where applicable. Preserve the host failure distinction and selected command identity. A target-free operation cannot recover by changing targets; a readable non-executable file does not have a read-access failure. The [provider guide](https://github.com/morluto/rea/blob/7dd6941393c852a3324cf01c2bd79a9dcff43728/docs/reverse-engineering-tools.md#L3-L19) documents caller-supplied GNU objdump and pathless architecture listing. The [lifecycle contract](https://github.com/morluto/rea/blob/7dd6941393c852a3324cf01c2bd79a9dcff43728/docs/tool-design.md#L78-L81) separates target admission from provider readiness. No particular replacement sentence or implementation is required. ### Impact and scope P2: bounded recovery misdirection for invalid provider selections. Six CLI failures reproduced on current main. Selecting an executable provider restored both fixture controls. The architecture listing has no artifact to change. No evidence corruption, downstream retry loop, or security boundary crossing was observed. Real GNU objdump analysis, MCP replay, Windows and Linux were not tested. ### REA version `rea-agents` 6.7.0. Independently verified baseline `9d8e7803326a382cbbb3ffdb900f5e93e5442d68`; rebuilt and replayed on `origin/main` at `7dd6941393c852a3324cf01c2bd79a9dcff43728`. Latest published release is `rea-agents-6.7.0`. ### Runtime and platform Node.js v26.12.0; macOS 27.0.1; arm64. ### Target and artifact context An inert readable text artifact for inspection; no artifact for architecture listing. Selected commands are an absent path, a directory, a readable non-executable shell file, and an otherwise equivalent executable shell-file control. HOME, XDG directories and temporary state are isolated. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence Observed missing-command error from both commands, exit 1: ```json {"code":"capability_unavailable","category":"unsupported_provider","message":"This analysis is unavailable for the current target. Choose another analysis or target.","retryable":false,"remediation":{"action":"This analysis is unavailable for the current target. Choose another analysis or target."},"details":{"provider_id":"objdump","operation":"inspect_with_objdump","reason":"Unable to run configured command (ENOENT)"}} ``` Directory and mode-0644 cases each return `access_denied`, category `unavailable`, `retryable: false`, `details.system_code: EACCES`, and `details.boundary: filesystem-read`. The executable path remains in `details.path`. Their exact message and remediation are: ```text Host filesystem permissions denied read access to the selected path. Check the current process's read access to the selected path. Retry with a readable local file. ``` Both executable controls preserve stdout `BFD test target\n` and `completion_status: complete`. Architecture listing returns `subject: null`; artifact inspection retains its digest and reports `artifact_changed: false`. Evidence provenance: observed; local verification: independently reproduced, then replayed on main. ### Typed outcome or recovery expected Keep all six invalid selections as failures while identifying the provider-launch boundary, selected executable and host error. Missing-command recovery should concern provider selection; EACCES recovery should concern executable selection or execution permission. Preserve both success controls and separate diagnostics for missing, invalid or unreadable artifacts. Those artifact regression checks are proposed, not executed here. ### Analysis or suspected cause Source-derived reasoning: [ReverseEngineeringService.ts](https://github.com/morluto/rea/blob/7dd6941393c852a3324cf01c2bd79a9dcff43728/src/application/reverse/ReverseEngineeringService.ts#L471-L509) maps early launch EACCES to `AnalysisAccessDeniedError` for the command, and ENOENT to a generic capability refusal without provider-specific recovery. `src/domain/analysisErrorPresentation.ts:124-128,249-250,373-377` supplies the read/target advice; `src/domain/analysisErrorProjection.ts:317-322` supplies `filesystem-read`. The selected command comes from `src/composition/reverseEngineering.ts:18-24`. ### Additional context Prepared with AI assistance. No fix or restoration was tested; the last known good version is unknown. Related #5401 concerns missing/directory artifact inputs before provider launch. This report selects invalid provider commands and also reproduces without an artifact, so it requires a separate recovery signal. #5177 concerns Apktool launcher permissions; #1952 concerns ADB advice; #3347 and #3337 concern Apktool timeout and process cleanup. Their provider-specific scopes do not cover this objdump failure. Open PR #1960 retains the generic ENOENT fallback and leaves this EACCES mapping unchanged.
Author
Owner

@matbrgz commented on GitHub (Oct 20, 2026):

Cross-referencing with canonical issue #5579 (Reverse engineering CLI commands drop stderr from objdump failures) and sibling failure classification reports #5449, #5507, #5642.

Consolidated under Cluster BP (Reverse Engineering Service Boundary Failure Classification & Objdump Error Handling) in tracker #4330.

<!-- gh-comment-id:6304476345 --> @matbrgz commented on GitHub (Oct 20, 2026): Cross-referencing with canonical issue #5579 (`Reverse engineering CLI commands drop stderr from objdump failures`) and sibling failure classification reports #5449, #5507, #5642. Consolidated under **Cluster BP (Reverse Engineering Service Boundary Failure Classification & Objdump Error Handling)** in tracker #4330.
Author
Owner

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

The same missing-provider launch diagnostic also affects Rizin and GDB. Independent Linux verification at baseline 9d8e7803326a382cbbb3ffdb900f5e93e5442d68 reproduced both; I additionally replayed Rizin with REA_RIZIN_COMMAND=/nonexistent/rizin node scripts/rea.mjs execute-rizin-command /bin/true iI --json. The GDB CLI reproduction is REA_GDB_COMMAND=/nonexistent/gdb node scripts/rea.mjs debug-with-gdb "show version" --inferior-tty /dev/tty --json (the CLI requires --inferior-tty). Both exit 1 with capability_unavailable and the message and remediation “This analysis is unavailable for the current target. Choose another analysis or target.” Rizin uses the same launch-error mapping as objdump, retaining Unable to run configured command (ENOENT) in details.reason; GDB reaches the same generic presentation through its startup error, retaining spawn /nonexistent/gdb ENOENT. Expected recovery should identify the missing configured executable (/nonexistent/rizin or /nonexistent/gdb) and the corresponding setting to correct (REA_RIZIN_COMMAND or REA_GDB_COMMAND), since changing the target cannot restore the executable. MCP was source-checked only. Main was fetched at d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f; relevant service code changed, so these triggers are verified at baseline; main not re-run.

<!-- gh-comment-id:6307190631 --> @coygeek commented on GitHub (Oct 21, 2026): The same missing-provider launch diagnostic also affects Rizin and GDB. Independent Linux verification at baseline `9d8e7803326a382cbbb3ffdb900f5e93e5442d68` reproduced both; I additionally replayed Rizin with `REA_RIZIN_COMMAND=/nonexistent/rizin node scripts/rea.mjs execute-rizin-command /bin/true iI --json`. The GDB CLI reproduction is `REA_GDB_COMMAND=/nonexistent/gdb node scripts/rea.mjs debug-with-gdb "show version" --inferior-tty /dev/tty --json` (the CLI requires `--inferior-tty`). Both exit 1 with `capability_unavailable` and the message and remediation “This analysis is unavailable for the current target. Choose another analysis or target.” Rizin uses the same launch-error mapping as objdump, retaining `Unable to run configured command (ENOENT)` in `details.reason`; GDB reaches the same generic presentation through its startup error, retaining `spawn /nonexistent/gdb ENOENT`. Expected recovery should identify the missing configured executable (`/nonexistent/rizin` or `/nonexistent/gdb`) and the corresponding setting to correct (`REA_RIZIN_COMMAND` or `REA_GDB_COMMAND`), since changing the target cannot restore the executable. MCP was source-checked only. Main was fetched at `d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f`; relevant service code changed, so these triggers are verified at baseline; main not re-run.
Author
Owner

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

Checked the reported fix on main at d87e73f2db.

Objdump launch failures now map to provider-specific capability refusal with selected executable, native system_code, provider-launch boundary and REA_OBJDUMP_COMMAND/execute/search-permission recovery, independently of whether a target was supplied. Target admission access errors remain filesystem-read. The same shared branch also names REA_RIZIN_COMMAND, addressing the author comment’s Rizin extension.

Implementation: ReverseEngineeringService.ts, reverseProviderLaunchErrors.test.ts.

The relevant regression checks in reverseProviderLaunchErrors.test.ts, gdbStartupCleanupCli.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.

<!-- gh-comment-id:6380722963 --> @coygeek commented on GitHub (Oct 24, 2026): Checked the reported fix on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. Objdump launch failures now map to provider-specific capability refusal with selected executable, native system_code, provider-launch boundary and REA_OBJDUMP_COMMAND/execute/search-permission recovery, independently of whether a target was supplied. Target admission access errors remain filesystem-read. The same shared branch also names REA_RIZIN_COMMAND, addressing the author comment’s Rizin extension. Implementation: [ReverseEngineeringService.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/application/reverse/ReverseEngineeringService.ts#L527), [reverseProviderLaunchErrors.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/composition/reverseProviderLaunchErrors.test.ts#L12). The relevant regression checks in [reverseProviderLaunchErrors.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/composition/reverseProviderLaunchErrors.test.ts), [gdbStartupCleanupCli.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/boundary/cli/gdbStartupCleanupCli.test.ts) passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. 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#3444
No description provided.