[GH-ISSUE #3055] [Bug] Unconfigured pwntools commands recommend rea doctor, which cannot diagnose pwntools #1069

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

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

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

On Linux x64 with REA_PWNTOOLS_PYTHON unset, inspect-binary-layout and inspect-recorded-crash fail with provider_unavailable whose top-level message and remediation.action say "Review the reported local diagnostics or run rea doctor, then retry." The diagnostics branch works: details.rejections[].reason names REA_PWNTOOLS_PYTHON. The doctor branch leads nowhere: unscoped rea doctor has no pwntools check, and the documented provider_unavailable recovery, rea doctor --provider ID --json, rejects the pwntools-elf provider ID as invalid. The same generic advice appears when REA_PWNTOOLS_PYTHON points to a directory or a missing file.

Step 2 exited 1 with:

{"code":"provider_unavailable","category":"unavailable","message":"The selected analysis provider is unavailable. Review the reported local diagnostics or run `rea doctor`, then retry.","retryable":true,"remediation":{"action":"The selected analysis provider is unavailable. Review the reported local diagnostics or run `rea doctor`, then retry."},"details":{"operation":"inspect_binary_layout","selection_reason":"provider_unavailable","requested_provider_id":"pwntools-elf","candidate_ids":["pwntools-elf"],"rejections":[{"provider_id":"pwntools-elf","code":"provider_unavailable","reason":"Set REA_PWNTOOLS_PYTHON to an absolute caller-supplied Python executable with pwntools 4.15.0, pyelftools 0.33 and Unicorn 2.1.2; REA never installs Python or packages.","diagnostics":{"configuration_key":"REA_PWNTOOLS_PYTHON","executable_path":""}}]}}

Step 3 exited 1 with the same message, remediation and rejection, with operation inspect_recorded_crash.

Step 4 exited 1. Its check names and provider IDs were:

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

No doctor field other than the embedded identity tool catalog mentions pwntools or REA_PWNTOOLS_PYTHON.

Step 5 exited 1 with code: "VALIDATION_ERROR" and Invalid option: expected one of "hopper"|"ghidra"|"ida".

Step 6 exited 1 both times with the same generic provider_unavailable message and remediation; the specific reasons were only in details.rejections[].reason: Selected Python executable must be a regular executable file, not a directory: /tmp and Selected Python executable is unavailable (ENOENT): /nonexistent/python3. Check the caller-selected path and execute access.

Step 7, the comparison: both commands exited 1 with capability_unavailable and a top-level message naming the variable to set, for example Provide an absolute REA_WAKARU_COMMAND pointing to a Wakaru ^1.13.0 Linux x64 binary (verified with 1.14.0); no tool is installed by REA. See docs/javascript-recovery.md#install-wakaru. and This integration requires Linux and an absolute REA_BINWALK_COMMAND path to the caller-supplied tool.

The main build reproduced steps 2 and 5 in the same container: inspect-binary-layout returned the same provider_unavailable message and remediation, and doctor --provider pwntools-elf exited 1 with the same VALIDATION_ERROR.

Reproduction

  1. On Linux x64, compile any ELF, for example printf 'int main(void){return 0;}\n' > hello.c && gcc -o hello hello.c.
  2. Run env -u REA_PWNTOOLS_PYTHON rea inspect-binary-layout "$PWD/hello" --json.
  3. Run env -u REA_PWNTOOLS_PYTHON rea inspect-recorded-crash "$PWD/hello" --json.
  4. Follow the advice: run rea doctor --json and look for a pwntools check in checks, scope_checks, informational_checks and providerInspections.
  5. Follow the documented provider-scoped recovery with the rejected provider's ID: rea doctor --provider pwntools-elf --json.
  6. Repeat step 2 with REA_PWNTOOLS_PYTHON=/tmp (a directory) and with REA_PWNTOOLS_PYTHON=/nonexistent/python3 (a missing file).
  7. For comparison, run env -u REA_WAKARU_COMMAND rea recover-javascript-sources "$PWD/app.js" "$PWD/out" --json with any small app.js, and rea inspect-firmware-regions "$PWD/hello" --json without REA_BINWALK_COMMAND.

Expected behavior

The CLI provider-selection guide says that for provider_unavailable the caller should "run rea doctor --provider ID --json to diagnose the selected engine". For the pwntools-elf rejection, that workflow should either diagnose REA_PWNTOOLS_PYTHON, or the failure's top-level message and remediation.action should name the requirement directly. The guide's sentence does not depend on the provider kind, the error carries the same provider_unavailable code, and the message itself recommends doctor; docs/installation.md also says unscoped doctor audits "optional analysis engines". Naming the requirement directly is what the project already does for comparable host and tool refusals: merged PR #1224 made optional-adapter refusals name what to configure, including the pwntools Linux x64 host refusal, and merged PR #2507 restated that invariant for the pcap tools. Issue #1125 reported the same doctor-advice pattern for Android and was closed as completed by #1145.

Impact and scope

  • Impact level: P3
  • Assessment status: supported
  • Impact basis: The failure is correctly classified and details.rejections[].reason names the exact variable and problem; only the doctor branch of the top-level recovery advice, and the documented doctor --provider route, lead to commands that cannot help, which costs a caller an extra diagnostic step without blocking the workflow or losing evidence.
  • Workaround status: available
  • Workaround basis: Reading details.rejections[].reason or docs/binary-diagnostics.md gives the variable to set; setting it is the documented configuration.

REA version

6.4.0 (npm rea-agents, tag rea-agents-6.4.0, commit a56f7bb668ab23fec8d33f7af353ac7ed2fe1895), installed into a disposable prefix with an isolated home; also reproduced on a source build of main at e049ef70f71aeb9965e9d75d4d4a84ea02eaee11.

Runtime and platform

  • Debian 12.15 in the node:24 container image (linux/amd64 platform on an arm64 Mac host), Node 24.21.0, npm 11.19.0.

Target and artifact context

Any gcc-built x86-64 ELF executable; no core file or pwntools installation is needed to reproduce.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

  • Expected source: docs/cli.md lines 96-99 at the release tag (provider-selection recovery via rea doctor --provider ID --json), with PRs #1224 and #2507 and issue #1125 as precedent for naming the prerequisite instead of recommending a diagnostic that cannot observe it.
  • Failure source: the step 2-6 outputs above; the message is the provider_unavailable case of providerSelectionUserMessage, and doctor's selectable providers are ["hopper", "ghidra", "ida"].
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Typed outcome or recovery expected

Failing now: steps 2, 3 and 6 return top-level advice to run rea doctor, and steps 4 and 5 show doctor cannot diagnose REA_PWNTOOLS_PYTHON. Restored: for the unset, directory and missing-file cases, the top-level message or remediation.action names REA_PWNTOOLS_PYTHON and the specific problem, or the recommended doctor workflow reports a pwntools check that identifies it. Controls: Hopper, Ghidra and IDA provider_unavailable failures still point to a doctor workflow that inspects them; a configured REA_PWNTOOLS_PYTHON still runs inspect-binary-layout.

Analysis or suspected cause

Source-derived, not a prescribed fix: The unconfigured, directory and missing-file paths throw pwntoolsUnavailable, which builds a ProviderSelectionError without a caller-specific message, so the generic provider_unavailable text is used. That message is shared by every provider_unavailable selection, including Hopper, Ghidra and IDA, which doctor does inspect; this report concerns only providers doctor cannot diagnose, observed here for pwntools-elf. The MCP capability inventory already carries a pwntools-specific remediation (src/application/CapabilityInventory.ts), so the requirement text exists outside the rejection detail.

Additional context

Related open issue #3008 asks doctor to report a provider row for every advertised MCP tool surface. It does not cover the CLI failure's recovery text, and this failure can be restored by changing the refusal's guidance alone.

Two other pwntoolsUnavailable call sites, the Python spawn failure and the engine-reply failure, use the same constructor and therefore the same generic message; they were identified from source and not executed. Setting REA_PWNTOOLS_PYTHON=/bin/true fails through a different path (unreadable_output, "Retry once; if it continues, run rea doctor.") and is outside this report.

Originally created by @coygeek on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3055 ### 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 On Linux x64 with `REA_PWNTOOLS_PYTHON` unset, `inspect-binary-layout` and `inspect-recorded-crash` fail with `provider_unavailable` whose top-level `message` and `remediation.action` say "Review the reported local diagnostics or run `rea doctor`, then retry." The diagnostics branch works: `details.rejections[].reason` names `REA_PWNTOOLS_PYTHON`. The doctor branch leads nowhere: unscoped `rea doctor` has no pwntools check, and the documented `provider_unavailable` recovery, `rea doctor --provider ID --json`, rejects the `pwntools-elf` provider ID as invalid. The same generic advice appears when `REA_PWNTOOLS_PYTHON` points to a directory or a missing file. Step 2 exited 1 with: ```json {"code":"provider_unavailable","category":"unavailable","message":"The selected analysis provider is unavailable. Review the reported local diagnostics or run `rea doctor`, then retry.","retryable":true,"remediation":{"action":"The selected analysis provider is unavailable. Review the reported local diagnostics or run `rea doctor`, then retry."},"details":{"operation":"inspect_binary_layout","selection_reason":"provider_unavailable","requested_provider_id":"pwntools-elf","candidate_ids":["pwntools-elf"],"rejections":[{"provider_id":"pwntools-elf","code":"provider_unavailable","reason":"Set REA_PWNTOOLS_PYTHON to an absolute caller-supplied Python executable with pwntools 4.15.0, pyelftools 0.33 and Unicorn 2.1.2; REA never installs Python or packages.","diagnostics":{"configuration_key":"REA_PWNTOOLS_PYTHON","executable_path":""}}]}} ``` Step 3 exited 1 with the same `message`, `remediation` and rejection, with `operation` `inspect_recorded_crash`. Step 4 exited 1. Its check names and provider IDs were: ```json {"checks":["node","host","hopper","ghidra","ida-registration","skill:identity"],"scope_checks":["node","host","hopper","ghidra","ida-registration","skill:identity"],"providerInspections":["ghidra","ida"]} ``` No doctor field other than the embedded `identity` tool catalog mentions pwntools or `REA_PWNTOOLS_PYTHON`. Step 5 exited 1 with `code: "VALIDATION_ERROR"` and `Invalid option: expected one of "hopper"|"ghidra"|"ida"`. Step 6 exited 1 both times with the same generic `provider_unavailable` `message` and `remediation`; the specific reasons were only in `details.rejections[].reason`: `Selected Python executable must be a regular executable file, not a directory: /tmp` and `Selected Python executable is unavailable (ENOENT): /nonexistent/python3. Check the caller-selected path and execute access.` Step 7, the comparison: both commands exited 1 with `capability_unavailable` and a top-level `message` naming the variable to set, for example `Provide an absolute REA_WAKARU_COMMAND pointing to a Wakaru ^1.13.0 Linux x64 binary (verified with 1.14.0); no tool is installed by REA. See docs/javascript-recovery.md#install-wakaru.` and `This integration requires Linux and an absolute REA_BINWALK_COMMAND path to the caller-supplied tool`. The `main` build reproduced steps 2 and 5 in the same container: `inspect-binary-layout` returned the same `provider_unavailable` message and remediation, and `doctor --provider pwntools-elf` exited 1 with the same `VALIDATION_ERROR`. ### Reproduction 1. On Linux x64, compile any ELF, for example `printf 'int main(void){return 0;}\n' > hello.c && gcc -o hello hello.c`. 2. Run `env -u REA_PWNTOOLS_PYTHON rea inspect-binary-layout "$PWD/hello" --json`. 3. Run `env -u REA_PWNTOOLS_PYTHON rea inspect-recorded-crash "$PWD/hello" --json`. 4. Follow the advice: run `rea doctor --json` and look for a pwntools check in `checks`, `scope_checks`, `informational_checks` and `providerInspections`. 5. Follow the documented provider-scoped recovery with the rejected provider's ID: `rea doctor --provider pwntools-elf --json`. 6. Repeat step 2 with `REA_PWNTOOLS_PYTHON=/tmp` (a directory) and with `REA_PWNTOOLS_PYTHON=/nonexistent/python3` (a missing file). 7. For comparison, run `env -u REA_WAKARU_COMMAND rea recover-javascript-sources "$PWD/app.js" "$PWD/out" --json` with any small `app.js`, and `rea inspect-firmware-regions "$PWD/hello" --json` without `REA_BINWALK_COMMAND`. ### Expected behavior The [CLI provider-selection guide](https://github.com/morluto/rea/blob/a56f7bb668ab23fec8d33f7af353ac7ed2fe1895/docs/cli.md?plain=1#L96-L99) says that for `provider_unavailable` the caller should "run `rea doctor --provider ID --json` to diagnose the selected engine". For the `pwntools-elf` rejection, that workflow should either diagnose `REA_PWNTOOLS_PYTHON`, or the failure's top-level `message` and `remediation.action` should name the requirement directly. The guide's sentence does not depend on the provider kind, the error carries the same `provider_unavailable` code, and the message itself recommends doctor; `docs/installation.md` also says unscoped doctor audits "optional analysis engines". Naming the requirement directly is what the project already does for comparable host and tool refusals: merged PR #1224 made optional-adapter refusals name what to configure, including the pwntools Linux x64 host refusal, and merged PR #2507 restated that invariant for the pcap tools. Issue #1125 reported the same doctor-advice pattern for Android and was closed as completed by #1145. ### Impact and scope - Impact level: P3 - Assessment status: supported - Impact basis: The failure is correctly classified and `details.rejections[].reason` names the exact variable and problem; only the doctor branch of the top-level recovery advice, and the documented `doctor --provider` route, lead to commands that cannot help, which costs a caller an extra diagnostic step without blocking the workflow or losing evidence. - Workaround status: available - Workaround basis: Reading `details.rejections[].reason` or `docs/binary-diagnostics.md` gives the variable to set; setting it is the documented configuration. ### REA version 6.4.0 (npm `rea-agents`, tag `rea-agents-6.4.0`, commit `a56f7bb668ab23fec8d33f7af353ac7ed2fe1895`), installed into a disposable prefix with an isolated home; also reproduced on a source build of `main` at `e049ef70f71aeb9965e9d75d4d4a84ea02eaee11`. ### Runtime and platform - Debian 12.15 in the `node:24` container image (linux/amd64 platform on an arm64 Mac host), Node 24.21.0, npm 11.19.0. ### Target and artifact context Any gcc-built x86-64 ELF executable; no core file or pwntools installation is needed to reproduce. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence - Expected source: `docs/cli.md` lines 96-99 at the release tag (provider-selection recovery via `rea doctor --provider ID --json`), with PRs #1224 and #2507 and issue #1125 as precedent for naming the prerequisite instead of recommending a diagnostic that cannot observe it. - Failure source: the step 2-6 outputs above; the message is the `provider_unavailable` case of [`providerSelectionUserMessage`](https://github.com/morluto/rea/blob/a56f7bb668ab23fec8d33f7af353ac7ed2fe1895/src/domain/providerSelectionError.ts#L82), and doctor's selectable providers are [`["hopper", "ghidra", "ida"]`](https://github.com/morluto/rea/blob/a56f7bb668ab23fec8d33f7af353ac7ed2fe1895/src/application/Doctor.ts#L40). - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete ### Typed outcome or recovery expected Failing now: steps 2, 3 and 6 return top-level advice to run `rea doctor`, and steps 4 and 5 show doctor cannot diagnose `REA_PWNTOOLS_PYTHON`. Restored: for the unset, directory and missing-file cases, the top-level `message` or `remediation.action` names `REA_PWNTOOLS_PYTHON` and the specific problem, or the recommended doctor workflow reports a pwntools check that identifies it. Controls: Hopper, Ghidra and IDA `provider_unavailable` failures still point to a doctor workflow that inspects them; a configured `REA_PWNTOOLS_PYTHON` still runs `inspect-binary-layout`. ### Analysis or suspected cause Source-derived, not a prescribed fix: The unconfigured, directory and missing-file paths throw `pwntoolsUnavailable`, which builds a `ProviderSelectionError` without a caller-specific message, so the generic `provider_unavailable` text is used. That message is shared by every `provider_unavailable` selection, including Hopper, Ghidra and IDA, which doctor does inspect; this report concerns only providers doctor cannot diagnose, observed here for `pwntools-elf`. The MCP capability inventory already carries a pwntools-specific remediation (`src/application/CapabilityInventory.ts`), so the requirement text exists outside the rejection detail. ### Additional context Related open issue #3008 asks doctor to report a provider row for every advertised MCP tool surface. It does not cover the CLI failure's recovery text, and this failure can be restored by changing the refusal's guidance alone. Two other `pwntoolsUnavailable` call sites, the Python spawn failure and the engine-reply failure, use the same constructor and therefore the same generic message; they were identified from source and not executed. Setting `REA_PWNTOOLS_PYTHON=/bin/true` fails through a different path (`unreadable_output`, "Retry once; if it continues, run `rea doctor`.") and is outside this report.
bsakaguchi 2026-10-15 18:30:49 +00:00
  • closed this issue
  • added the
    bug
    label
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#1069
No description provided.