[PR #4590] [MERGED] fix(ghidra): name the startup deadline setting when startup times out #6327

Closed
opened 2026-10-31 01:13:36 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4590
Author: @RishTheFish21
Created: 10/16/2026
Status: ✅ Merged
Merged: 10/16/2026
Merged by: @morluto

Base: main ← Head: fix/4241-startup-timeout


📝 Commits (1)

  • 1a573f0 fix(ghidra): name the startup deadline setting when startup times out

📊 Changes

9 files changed (+108 additions, -12 deletions)

View changed files

📝 docs/installation.md (+3 -0)
📝 src/domain/analysisErrorCore.ts (+10 -1)
📝 src/domain/analysisErrorPresentation.ts (+6 -0)
📝 src/ghidra/GhidraClient.ts (+2 -1)
📝 src/ghidra/GhidraClientStartup.ts (+5 -4)
📝 src/ghidra/GhidraProvider.behavior.test.ts (+58 -0)
📝 src/ghidra/GhidraProviderClient.ts (+17 -4)
📝 src/ghidra/GhidraSessionError.ts (+4 -0)
📝 src/ghidra/GhidraSocketConnection.ts (+3 -2)

📄 Description

Summary

When Ghidra doesn't finish importing and analyzing a target within its startup deadline, REA reports provider_timeout with the generic "Analysis took too long. Try a smaller request, then run rea doctor if it continues." For a large binary that's the wrong advice: the request isn't too big, the deadline is too short, and rea doctor reports Ghidra as healthy. The setting that controls it, REA_GHIDRA_STARTUP_TIMEOUT_MS, is only mentioned in docs/installation.md.

A Ghidra startup timeout now names the deadline that was applied and the settings that change it.

Fixes #4241. The memory half of the issue landed in d52a488 (from #4275). This PR covers its second request. The optional third idea, surfacing analyzer messages like "Untested Go version" as limitations, isn't included.

Problem and expected behavior

Smallest trigger: REA_GHIDRA_STARTUP_TIMEOUT_MS=5000 rea inspect "$(command -v node)" --provider ghidra --json.

Expected: the error says which deadline elapsed and how to change it, without sending the user to rea doctor. A timeout on an individual bridge request is a different deadline and should keep its current wording.

Hopper already does this: its startup timeout remediation names REA_HOPPER_STARTUP_TIMEOUT_MS. Ghidra's equivalent setting is never mentioned in its timeout error.

Change and scope

  • GhidraProviderClient.ts: a timeout failure carrying the startup-deadline message now gets a user message naming the applied deadline and REA_GHIDRA_STARTUP_TIMEOUT_MS, plus remediation to raise it or skip expensive analyzers with REA_GHIDRA_DISABLED_ANALYZERS. The remediation also notes that the MCP client's own tool-call timeout is separate.
  • GhidraSessionError.ts: the five places that raise the startup timeout (GhidraClient, GhidraClientStartup, and two in GhidraSocketConnection) share one GHIDRA_STARTUP_DEADLINE_ELAPSED constant, so the projection can't drift from them.
  • AnalysisTimeoutError accepts an optional provider-specific userMessage and remediationAction, and the error presentation uses them when present. Every other timeout keeps its current text.
  • docs/installation.md: notes the new guidance next to the REA_GHIDRA_STARTUP_TIMEOUT_MS description.

Bridge request deadlines and the per-file auto-analysis deadline (analysis_timeout) are unchanged.

Follow the contribution scope.
Unresolved scope, authority, side effects, or required verification block
integration. Link the required maintainer scope decision for new providers or
capabilities involving target execution, injection, mutation, or protection
recovery; ordinary fixes within existing boundaries may state "not applicable".
Draft PRs may leave the scope decision pending and the readiness and merge checklists
unchecked. Maintainers can help resolve open questions.

Contract and boundary impact

  • Semantic owner and earliest changed stage: Ghidra session error projection (projectPrimarySessionError); provider-neutral AnalysisTimeoutError presentation.
  • Contribution scope fit and linked maintainer decision: Bug fix within existing boundaries. Maintainer decision not applicable.
  • CLI and MCP/tool-catalog contract: Same provider_timeout code and details.timeout_ms. Only the message and remediation.action text change, and only for Ghidra startup timeouts.
  • Provider, bridge, target-format, or platform compatibility: Ghidra only. No bridge change. Hopper timeouts are unaffected.
  • Evidence, artifact, provenance, or reconstruction contract: Error path only. No Evidence or profile change.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): Not applicable.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact (CI generates and validates ignored catalogs and skills/; edit authored instructions in .agents/skills/reverse-engineer-anything/ and never commit build outputs): None.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: src/ghidra/GhidraProvider.behavior.test.ts, "Ghidra deadline guidance":
    • A startup-deadline timeout projects to provider_timeout with timeout_ms: 250, a message naming the 250 ms deadline and REA_GHIDRA_STARTUP_TIMEOUT_MS, and remediation naming both settings without rea doctor.
    • A bridge request timeout keeps the generic guidance.
  • Base reproduction or other evidence: Real Ghidra 12.1.4 on macOS arm64, REA_GHIDRA_STARTUP_TIMEOUT_MS=5000 rea inspect "$(command -v node)" --provider ghidra --json:
    • upstream/main: "code":"provider_timeout", message and action both Analysis took too long. Try a smaller request, then run \rea doctor` if it continues.`
    • this branch: "code":"provider_timeout", message Ghidra did not finish importing and analyzing the target within its 5000 ms startup deadline (REA_GHIDRA_STARTUP_TIMEOUT_MS)., action Large binaries can need longer: set REA_GHIDRA_STARTUP_TIMEOUT_MS above 5000 in the environment that starts REA, or skip expensive analyzers with REA_GHIDRA_DISABLED_ANALYZERS, then open the target again. An MCP client's own tool-call timeout is separate and may also need raising.
  • User-visible CLI/MCP output (if applicable): see above.
  • Remaining proof gaps: Not run on Linux or Windows. The startup timeout is recognized by its shared message constant rather than a dedicated failure kind; a dedicated kind would be cleaner but touches every timeout consumer.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npm run test:focused -- src/ghidra/GhidraProvider.behavior.test.ts tests/boundary/providers/ghidra/ghidraJavaLaunch.test.ts: passed
  • npm run check:fast: passed
  • npm run lint: passed
  • npm run knip: passed
  • npm run docs:check: passed
  • Real Ghidra 12.1.4 before/after run on macOS arm64 (above)

Compatibility, safety, and release

  • Breaking changes or migration steps: None. Same error code and details; only the message and remediation text for Ghidra startup timeouts change.
  • Real Hopper/Ghidra, browser, or OS coverage: Real Ghidra 12.1.4 on macOS arm64.
  • Package or release metadata impact: None.
  • Security, privacy, process, or containment review: Text-only change to an existing error path.

Author readiness

Human owner: @RishTheFish21

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4590 **Author:** [@RishTheFish21](https://github.com/RishTheFish21) **Created:** 10/16/2026 **Status:** ✅ Merged **Merged:** 10/16/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/4241-startup-timeout` --- ### 📝 Commits (1) - [`1a573f0`](https://github.com/morluto/rea/commit/1a573f0ffb3978a0a8479161479f5a00bdd698fd) fix(ghidra): name the startup deadline setting when startup times out ### 📊 Changes **9 files changed** (+108 additions, -12 deletions) <details> <summary>View changed files</summary> 📝 `docs/installation.md` (+3 -0) 📝 `src/domain/analysisErrorCore.ts` (+10 -1) 📝 `src/domain/analysisErrorPresentation.ts` (+6 -0) 📝 `src/ghidra/GhidraClient.ts` (+2 -1) 📝 `src/ghidra/GhidraClientStartup.ts` (+5 -4) 📝 `src/ghidra/GhidraProvider.behavior.test.ts` (+58 -0) 📝 `src/ghidra/GhidraProviderClient.ts` (+17 -4) 📝 `src/ghidra/GhidraSessionError.ts` (+4 -0) 📝 `src/ghidra/GhidraSocketConnection.ts` (+3 -2) </details> ### 📄 Description ## Summary When Ghidra doesn't finish importing and analyzing a target within its startup deadline, REA reports `provider_timeout` with the generic "Analysis took too long. Try a smaller request, then run `rea doctor` if it continues." For a large binary that's the wrong advice: the request isn't too big, the deadline is too short, and `rea doctor` reports Ghidra as healthy. The setting that controls it, `REA_GHIDRA_STARTUP_TIMEOUT_MS`, is only mentioned in `docs/installation.md`. A Ghidra startup timeout now names the deadline that was applied and the settings that change it. Fixes #4241. The memory half of the issue landed in d52a488 (from #4275). This PR covers its second request. The optional third idea, surfacing analyzer messages like "Untested Go version" as limitations, isn't included. ## Problem and expected behavior Smallest trigger: `REA_GHIDRA_STARTUP_TIMEOUT_MS=5000 rea inspect "$(command -v node)" --provider ghidra --json`. Expected: the error says which deadline elapsed and how to change it, without sending the user to `rea doctor`. A timeout on an individual bridge request is a different deadline and should keep its current wording. Hopper already does this: its startup timeout remediation names `REA_HOPPER_STARTUP_TIMEOUT_MS`. Ghidra's equivalent setting is never mentioned in its timeout error. ## Change and scope - `GhidraProviderClient.ts`: a `timeout` failure carrying the startup-deadline message now gets a user message naming the applied deadline and `REA_GHIDRA_STARTUP_TIMEOUT_MS`, plus remediation to raise it or skip expensive analyzers with `REA_GHIDRA_DISABLED_ANALYZERS`. The remediation also notes that the MCP client's own tool-call timeout is separate. - `GhidraSessionError.ts`: the five places that raise the startup timeout (`GhidraClient`, `GhidraClientStartup`, and two in `GhidraSocketConnection`) share one `GHIDRA_STARTUP_DEADLINE_ELAPSED` constant, so the projection can't drift from them. - `AnalysisTimeoutError` accepts an optional provider-specific `userMessage` and `remediationAction`, and the error presentation uses them when present. Every other timeout keeps its current text. - `docs/installation.md`: notes the new guidance next to the `REA_GHIDRA_STARTUP_TIMEOUT_MS` description. Bridge request deadlines and the per-file auto-analysis deadline (`analysis_timeout`) are unchanged. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Unresolved scope, authority, side effects, or required verification block integration. Link the required maintainer scope decision for new providers or capabilities involving target execution, injection, mutation, or protection recovery; ordinary fixes within existing boundaries may state "not applicable". Draft PRs may leave the scope decision pending and the readiness and merge checklists unchecked. Maintainers can help resolve open questions. ## Contract and boundary impact - Semantic owner and earliest changed stage: Ghidra session error projection (`projectPrimarySessionError`); provider-neutral `AnalysisTimeoutError` presentation. - Contribution scope fit and linked maintainer decision: Bug fix within existing boundaries. Maintainer decision not applicable. - CLI and MCP/tool-catalog contract: Same `provider_timeout` code and `details.timeout_ms`. Only the message and `remediation.action` text change, and only for Ghidra startup timeouts. - Provider, bridge, target-format, or platform compatibility: Ghidra only. No bridge change. Hopper timeouts are unaffected. - Evidence, artifact, provenance, or reconstruction contract: Error path only. No Evidence or profile change. - Target selection, authority, upstream behavior, and cleanup details (if applicable): Not applicable. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs): None. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: `src/ghidra/GhidraProvider.behavior.test.ts`, "Ghidra deadline guidance": - A startup-deadline timeout projects to `provider_timeout` with `timeout_ms: 250`, a message naming the 250 ms deadline and `REA_GHIDRA_STARTUP_TIMEOUT_MS`, and remediation naming both settings without `rea doctor`. - A bridge request timeout keeps the generic guidance. - Base reproduction or other evidence: Real Ghidra 12.1.4 on macOS arm64, `REA_GHIDRA_STARTUP_TIMEOUT_MS=5000 rea inspect "$(command -v node)" --provider ghidra --json`: - upstream/main: `"code":"provider_timeout"`, message and action both `Analysis took too long. Try a smaller request, then run \`rea doctor\` if it continues.` - this branch: `"code":"provider_timeout"`, message `Ghidra did not finish importing and analyzing the target within its 5000 ms startup deadline (REA_GHIDRA_STARTUP_TIMEOUT_MS).`, action `Large binaries can need longer: set REA_GHIDRA_STARTUP_TIMEOUT_MS above 5000 in the environment that starts REA, or skip expensive analyzers with REA_GHIDRA_DISABLED_ANALYZERS, then open the target again. An MCP client's own tool-call timeout is separate and may also need raising.` - User-visible CLI/MCP output (if applicable): see above. - Remaining proof gaps: Not run on Linux or Windows. The startup timeout is recognized by its shared message constant rather than a dedicated failure kind; a dedicated kind would be cleaner but touches every timeout consumer. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npm run test:focused -- src/ghidra/GhidraProvider.behavior.test.ts tests/boundary/providers/ghidra/ghidraJavaLaunch.test.ts`: passed - `npm run check:fast`: passed - `npm run lint`: passed - `npm run knip`: passed - `npm run docs:check`: passed - Real Ghidra 12.1.4 before/after run on macOS arm64 (above) ## Compatibility, safety, and release - Breaking changes or migration steps: None. Same error code and details; only the message and remediation text for Ghidra startup timeouts change. - Real Hopper/Ghidra, browser, or OS coverage: Real Ghidra 12.1.4 on macOS arm64. - Package or release metadata impact: None. - Security, privacy, process, or containment review: Text-only change to an existing error path. ## Author readiness Human owner: @RishTheFish21 - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:13:36 +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#6327
No description provided.