[GH-ISSUE #3268] [Bug]: Hopper provider - 120s bridge-readiness deadline is hardcoded — long-analysis targets can never open #1169

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

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

[Bug]: Hopper provider - 120 s bridge-readiness deadline is hardcoded — targets whose initial analysis takes longer can never be opened

Environment

  • rea-agents 6.4.0 (npm, latest publish, 2026-10-11) — both MCP server (npx -y rea-agents@6.4.0 mcp) and CLI
  • Hopper Disassembler 6.6.0 (macOS vendor launcher)
  • macOS 27.0.1, Apple Silicon (arm64)

Summary

The Hopper bridge bootstrap script is executed by Hopper only after initial analysis has ended, but REA's bridge-readiness deadline is a hardcoded 120 000 ms that starts at launch. Any target whose initial Hopper analysis takes longer than ~2 minutes therefore can never be opened as an executable — the bridge physically cannot register in time. Unlike Ghidra, the Hopper timeout has no configuration surface at all (no env var, no setting).

Evidence (6.4.0 dist)

  • dist/hopper/HopperClient.js:95 — startupTimeoutMs: options.startupTimeoutMs ?? 120_000
  • dist/hopper/HopperProvider.js:150–178 — new HopperClient({...}) is constructed without startupTimeoutMs, so the 120 s default always applies.
  • dist/config/environment.js:34 — Ghidra has REA_GHIDRA_STARTUP_TIMEOUT_MS (schema in dist/config/ghidraStartupTimeout.js, default 330 s). There is no Hopper equivalent; the only process.env.REA_* read in the whole dist is REA_BUILD_COMMIT.
  • Hopper's own vendor launcher documents the ordering constraint:
    -Y | --python script.py Execute a Python script, once the initial analysis is ended.
    and bridge/hopper_bridge.py's docstring confirms the bootstrap is executed via that --python launcher option.

So readiness is gated on analysis completion, while the deadline is fixed at launch.

Reproduction

  1. Take a ~10 MB arm64 Mach-O whose Hopper initial analysis takes ≈4 min (e.g. a large framework binary).
  2. open_binary with provider_id: "hopper" (or rea analyze <path> --provider hopper).
  3. First provider query (e.g. list_documents) fails after exactly 120 s:
provider_timeout / stage: "startup" / timeout_ms: 120000 / provider_state: "not_started"
"Hopper may be waiting for a loader or license dialog…"
  1. Meanwhile Hopper finishes analysis normally (~4 min, document loads and analyzes correctly) — nothing was wrong except the elapsed time. A 75 KB binary with the same flow succeeds immediately, confirming the deadline is the only variable.

Actual vs. expected

  • Actual: hard failure, non-retryable (cleanup_incomplete), and the remediation text ("loader or license dialog") misdirects to a nonexistent dialog.
  • Expected: large real-world binaries should be openable; at minimum the deadline should be configurable like Ghidra's.

Suggested fix

  1. Add REA_HOPPER_STARTUP_TIMEOUT_MS mirroring REA_GHIDRA_STARTUP_TIMEOUT_MS (same zod schema, wired through config/environment.js → HopperProvider → HopperClient), and consider raising the default (Ghidra uses 330 s).
  2. Optionally decouple readiness from analysis: register the bridge at launch and expose "analysis in progress" as a queryable state, so the deadline only covers the handshake itself.
  3. Improve the timeout remediation text to mention "initial analysis longer than the startup deadline" as a cause.

Workaround today (and its limits)

Pre-analyze once with the vendor launcher and save the .hop (saveDocumentAt), then open_binary the database — loading is near-instant. But this workaround is itself blocked by the cleanup-wedge bug (separate issue) whenever Hopper has to be killed, and it requires users to know the deadline exists at all.

Originally created by @trigger2k20 on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3268 [Bug]: Hopper provider - 120 s bridge-readiness deadline is hardcoded — targets whose initial analysis takes longer can never be opened **Environment** - rea-agents **6.4.0** (npm, latest publish, 2026-10-11) — both MCP server (`npx -y rea-agents@6.4.0 mcp`) and CLI - Hopper Disassembler **6.6.0** (macOS vendor launcher) - macOS 27.0.1, Apple Silicon (arm64) ## Summary The Hopper bridge bootstrap script is executed by Hopper only **after initial analysis has ended**, but REA's bridge-readiness deadline is a hardcoded **120 000 ms** that starts at launch. Any target whose initial Hopper analysis takes longer than ~2 minutes therefore can *never* be opened as an executable — the bridge physically cannot register in time. Unlike Ghidra, the Hopper timeout has **no configuration surface at all** (no env var, no setting). ## Evidence (6.4.0 dist) - `dist/hopper/HopperClient.js:95` — `startupTimeoutMs: options.startupTimeoutMs ?? 120_000` - `dist/hopper/HopperProvider.js:150–178` — `new HopperClient({...})` is constructed **without** `startupTimeoutMs`, so the 120 s default always applies. - `dist/config/environment.js:34` — Ghidra has `REA_GHIDRA_STARTUP_TIMEOUT_MS` (schema in `dist/config/ghidraStartupTimeout.js`, default 330 s). There is **no Hopper equivalent**; the only `process.env.REA_*` read in the whole dist is `REA_BUILD_COMMIT`. - Hopper's own vendor launcher documents the ordering constraint: `-Y | --python script.py Execute a Python script, once the initial analysis is ended.` and `bridge/hopper_bridge.py`'s docstring confirms the bootstrap is executed via that `--python` launcher option. So readiness is gated on analysis completion, while the deadline is fixed at launch. ## Reproduction 1. Take a ~10 MB arm64 Mach-O whose Hopper initial analysis takes ≈4 min (e.g. a large framework binary). 2. `open_binary` with `provider_id: "hopper"` (or `rea analyze <path> --provider hopper`). 3. First provider query (e.g. `list_documents`) fails after exactly 120 s: ``` provider_timeout / stage: "startup" / timeout_ms: 120000 / provider_state: "not_started" "Hopper may be waiting for a loader or license dialog…" ``` 4. Meanwhile Hopper finishes analysis normally (~4 min, document loads and analyzes correctly) — nothing was wrong except the elapsed time. A 75 KB binary with the same flow succeeds immediately, confirming the deadline is the only variable. ## Actual vs. expected - **Actual:** hard failure, non-retryable (`cleanup_incomplete`), and the remediation text ("loader or license dialog") misdirects to a nonexistent dialog. - **Expected:** large real-world binaries should be openable; at minimum the deadline should be configurable like Ghidra's. ## Suggested fix 1. Add `REA_HOPPER_STARTUP_TIMEOUT_MS` mirroring `REA_GHIDRA_STARTUP_TIMEOUT_MS` (same zod schema, wired through `config/environment.js` → `HopperProvider` → `HopperClient`), and consider raising the default (Ghidra uses 330 s). 2. Optionally decouple readiness from analysis: register the bridge at launch and expose "analysis in progress" as a queryable state, so the deadline only covers the handshake itself. 3. Improve the timeout remediation text to mention "initial analysis longer than the startup deadline" as a cause. ## Workaround today (and its limits) Pre-analyze once with the vendor launcher and save the `.hop` (`saveDocumentAt`), then `open_binary` the database — loading is near-instant. But this workaround is itself blocked by the cleanup-wedge bug (separate issue) whenever Hopper has to be killed, and it requires users to know the deadline exists at all.
bsakaguchi 2026-10-15 18:31:42 +00:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@trigger2k20 commented on GitHub (Oct 14, 2026):

Related: #1808 already reports the hardcoded 120-second Hopper startup timeout and requests configurability.

This issue focuses on the interaction between that deadline and the vendor launcher executing the bridge bootstrap only after initial analysis completes. Targets whose analysis exceeds the default deadline cannot complete bridge startup within that deadline.

Please track this as a focused follow-up to #1808. The broader crash and session-recovery problems remain separate.

<!-- gh-comment-id:6163061489 --> @trigger2k20 commented on GitHub (Oct 14, 2026): Related: #1808 already reports the hardcoded 120-second Hopper startup timeout and requests configurability. This issue focuses on the interaction between that deadline and the vendor launcher executing the bridge bootstrap only after initial analysis completes. Targets whose analysis exceeds the default deadline cannot complete bridge startup within that deadline. Please track this as a focused follow-up to #1808. The broader crash and session-recovery problems remain separate.
Author
Owner

@trigger2k20 commented on GitHub (Oct 14, 2026):

Overlaps with #1808. Additional analysis-ordering evidence, reproduction observations, and requested timeout improvements have been consolidated there. Please track the startup-timeout fix in #1808.

<!-- gh-comment-id:6163118935 --> @trigger2k20 commented on GitHub (Oct 14, 2026): Overlaps with #1808. Additional analysis-ordering evidence, reproduction observations, and requested timeout improvements have been consolidated there. Please track the startup-timeout fix in #1808.
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#1169
No description provided.