[GH-ISSUE #8415] [Bug] Address context hides rejected address and document details #6594

Open
opened 2026-11-01 21:12:31 +00:00 by bsakaguchi · 5 comments
Owner

Originally created by @morluto on GitHub (Nov 1, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8415

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

MCP or agent integration

Observed behavior

inspect_address_context returns a successful aggregate with generic unavailable facets when its explicit address or document is rejected as invalid by the available provider operations. The structured reason needed to correct the caller's request is lost.

Reproduction

On REA 6e9ee97a, open an owned arm64 Mach-O using Ghidra 12.1.4 or Kuna 1.986, then use list_documents to obtain the actual document:

  1. Call address_name with a known mapped function address and a different, non-existent document. Both providers returned invalid_request. Kuna identifies document in details.issues; Ghidra reports the unknown Program identity and active Program in the issue message.
  2. Call inspect_address_context with that same address and wrong document. Both returned success: name.state was unavailable with only Invalid analysis input for address_name and a suggestion to call the underlying operation directly. Ghidra's containing-procedure facet was also unavailable; Kuna did not declare that capability.
  3. With the correct document and address garbage, direct address_name returned invalid_request for the address on both providers. inspect_address_context again returned success with the same generic name-facet reason.
  4. With the same correct document and known mapped address, the aggregate succeeded and returned an available name; Ghidra also returned the containing function. The target hash was unchanged.

Expected behavior

Preserve the actionable request error and its typed field details when the caller's selected input is rejected. Whether to fail the whole aggregate or retain an explicit typed per-facet failure when other facets provide valid observations needs a decision. Do not turn unrelated facet-local limitations into global request failures, silently substitute a different document, infer identity from messages, or reject provider-valid address spellings without verifying their contracts.

Impact and scope

An agent receives a successful result and cannot see the actual document/address issue without an extra call. This is a scripted observation, not a measured autonomous-agent failure rate. One source-owned fixture, one host, and the listed provider versions were tested; other providers, CLI, concurrent changes and mixed successful/invalid facets are unverified.

REA version

6e9ee97a69cb16c7150d8b550e705cba055ee4f0.

Runtime and platform

Node 24.22.1, macOS arm64, Ghidra 12.1.4/JDK 21, Kuna 1.986, MCP TypeScript SDK 2.3.1.

Target and artifact context

Source-owned unexecuted arm64 Mach-O, SHA-256 ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d, unchanged by both runs.

Interface

MCP stdio with fetched full output schemas.

Earliest failure stage

Transport or result projection.

Relevant output or evidence

For the wrong document, the aggregate name facet was { "state": "unavailable", "reason": "Invalid analysis input for address_name", "remediation": "Call address_name directly to inspect provider availability and diagnostics." }; the direct call reported invalid_request and a document-specific issue. Both runs used the same chosen input for the direct and aggregate controls.

Typed outcome or recovery expected

Keep the actual AnalysisInputError issue paths and provider diagnostics available to the caller, distinguish it from a capability-unavailable facet, and retain any genuinely valid partial observations without assuming all providers share one address grammar.

Analysis or suspected cause

Source-derived: addressContextInputSchema accepts a nonempty address string. inspectAddressContext treats cancellation, timeout and no-open-target as request-level failures, but renders other errors as a facet using only error.message, dropping structured issues. Confirm how to distinguish rejected shared inputs from truly local errors and how partial results should be retained before choosing a fix.

Additional context

Related #8363 concerns unavailable comment recovery; #8364 concerns Evidence handoff. Last known good version: NOT_ENOUGH_INFO.

cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

Originally created by @morluto on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8415 ### 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 MCP or agent integration ### Observed behavior `inspect_address_context` returns a successful aggregate with generic unavailable facets when its explicit address or document is rejected as invalid by the available provider operations. The structured reason needed to correct the caller's request is lost. ### Reproduction On REA `6e9ee97a`, open an owned arm64 Mach-O using Ghidra 12.1.4 or Kuna 1.986, then use `list_documents` to obtain the actual document: 1. Call `address_name` with a known mapped function address and a different, non-existent document. Both providers returned `invalid_request`. Kuna identifies `document` in `details.issues`; Ghidra reports the unknown Program identity and active Program in the issue message. 2. Call `inspect_address_context` with that same address and wrong document. Both returned success: `name.state` was `unavailable` with only `Invalid analysis input for address_name` and a suggestion to call the underlying operation directly. Ghidra's containing-procedure facet was also unavailable; Kuna did not declare that capability. 3. With the correct document and address `garbage`, direct `address_name` returned `invalid_request` for the address on both providers. `inspect_address_context` again returned success with the same generic name-facet reason. 4. With the same correct document and known mapped address, the aggregate succeeded and returned an available name; Ghidra also returned the containing function. The target hash was unchanged. ### Expected behavior Preserve the actionable request error and its typed field details when the caller's selected input is rejected. Whether to fail the whole aggregate or retain an explicit typed per-facet failure when other facets provide valid observations needs a decision. Do not turn unrelated facet-local limitations into global request failures, silently substitute a different document, infer identity from messages, or reject provider-valid address spellings without verifying their contracts. ### Impact and scope An agent receives a successful result and cannot see the actual document/address issue without an extra call. This is a scripted observation, not a measured autonomous-agent failure rate. One source-owned fixture, one host, and the listed provider versions were tested; other providers, CLI, concurrent changes and mixed successful/invalid facets are unverified. ### REA version `6e9ee97a69cb16c7150d8b550e705cba055ee4f0`. ### Runtime and platform Node 24.22.1, macOS arm64, Ghidra 12.1.4/JDK 21, Kuna 1.986, MCP TypeScript SDK 2.3.1. ### Target and artifact context Source-owned unexecuted arm64 Mach-O, SHA-256 `ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d`, unchanged by both runs. ### Interface MCP stdio with fetched full output schemas. ### Earliest failure stage Transport or result projection. ### Relevant output or evidence For the wrong document, the aggregate name facet was `{ "state": "unavailable", "reason": "Invalid analysis input for address_name", "remediation": "Call address_name directly to inspect provider availability and diagnostics." }`; the direct call reported `invalid_request` and a document-specific issue. Both runs used the same chosen input for the direct and aggregate controls. ### Typed outcome or recovery expected Keep the actual `AnalysisInputError` issue paths and provider diagnostics available to the caller, distinguish it from a capability-unavailable facet, and retain any genuinely valid partial observations without assuming all providers share one address grammar. ### Analysis or suspected cause Source-derived: [`addressContextInputSchema`](https://github.com/morluto/rea/blob/6e9ee97a69cb16c7150d8b550e705cba055ee4f0/src/contracts/sessionToolSchemas.ts) accepts a nonempty address string. [`inspectAddressContext`](https://github.com/morluto/rea/blob/6e9ee97a69cb16c7150d8b550e705cba055ee4f0/src/application/AnalysisContextQueries.ts) treats cancellation, timeout and no-open-target as request-level failures, but renders other errors as a facet using only `error.message`, dropping structured issues. Confirm how to distinguish rejected shared inputs from truly local errors and how partial results should be retained before choosing a fix. ### Additional context Related #8363 concerns unavailable comment recovery; #8364 concerns Evidence handoff. Last known good version: NOT_ENOUGH_INFO. cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0
Author
Owner

@morluto commented on GitHub (Nov 1, 2026):

A real Ghidra control on draft #8414 head a3f0b22d2 still reproduces both wrong-document and malformed-address cases: the direct calls return invalid_request, while the context response succeeds with generic input-error facets. That PR improves capability-unavailable recovery and does not fix this request-error issue.

<!-- gh-comment-id:6552013771 --> @morluto commented on GitHub (Nov 1, 2026): A real Ghidra control on draft #8414 head `a3f0b22d2` still reproduces both wrong-document and malformed-address cases: the direct calls return `invalid_request`, while the context response succeeds with generic input-error facets. That PR improves capability-unavailable recovery and does not fix this request-error issue.
Author
Owner

@morluto commented on GitHub (Nov 1, 2026):

A controlled application-boundary experiment shows why simply propagating every AnalysisInputError as a whole-request failure would be too broad. A simulated provider returned an available name, a valid containing-function resolution and an empty bookmark list for 0x401001, while only its comment operation returned a specific AnalysisInputError with an address issue. The aggregate preserved the successful facets but reduced that error to the generic unavailable reason and lost its structured issue. I exercised both conformsToInputContract: false and true error variants; both behaved this way.

This is a controlled synthetic provider, not a real-Ghidra or real-Kuna mixed-outcome reproduction. It supports preserving the actual typed facet error alongside valid partial observations; it does not establish which malformed shared inputs should fail the entire request or justify parsing provider message text.

<!-- gh-comment-id:6552017395 --> @morluto commented on GitHub (Nov 1, 2026): A controlled application-boundary experiment shows why simply propagating every `AnalysisInputError` as a whole-request failure would be too broad. A simulated provider returned an available name, a valid containing-function resolution and an empty bookmark list for `0x401001`, while only its comment operation returned a specific `AnalysisInputError` with an address issue. The aggregate preserved the successful facets but reduced that error to the generic unavailable reason and lost its structured issue. I exercised both `conformsToInputContract: false` and `true` error variants; both behaved this way. This is a controlled synthetic provider, not a real-Ghidra or real-Kuna mixed-outcome reproduction. It supports preserving the actual typed facet error alongside valid partial observations; it does not establish which malformed shared inputs should fail the entire request or justify parsing provider message text.
Author
Owner

@morluto commented on GitHub (Nov 1, 2026):

Draft #8419 preserves the existing typed invalid_request projection on each unavailable facet while retaining successful siblings. It is stacked on #8417 so an incomplete cleanup remains a top-level failure.

Real Ghidra 12.1.4 and Kuna 1.986 wrong-document and malformed-address MCP controls now preserve the direct operation's issue details under both advertised schema profiles. A controlled mixed-facet test covers partial success; it is not a real-provider mixed-outcome reproduction.

The added field breaks clients validating against a cached strict full schema; refreshing tools/list is required. Keeping exact facet diagnostics can also increase response size: the measured Ghidra wrong-document response grew from 225 to 1,881 o200k_base tokens. Large-diagnostic response-budget behavior is unverified and aggregate Evidence handoff remains #8364.

<!-- gh-comment-id:6552263654 --> @morluto commented on GitHub (Nov 1, 2026): Draft #8419 preserves the existing typed `invalid_request` projection on each unavailable facet while retaining successful siblings. It is stacked on #8417 so an incomplete cleanup remains a top-level failure. Real Ghidra 12.1.4 and Kuna 1.986 wrong-document and malformed-address MCP controls now preserve the direct operation's issue details under both advertised schema profiles. A controlled mixed-facet test covers partial success; it is not a real-provider mixed-outcome reproduction. The added field breaks clients validating against a cached strict full schema; refreshing `tools/list` is required. Keeping exact facet diagnostics can also increase response size: the measured Ghidra wrong-document response grew from 225 to 1,881 `o200k_base` tokens. Large-diagnostic response-budget behavior is unverified and aggregate Evidence handoff remains #8364.
Author
Owner

@morluto commented on GitHub (Nov 1, 2026):

Real-provider follow-up on draft #8426 stack 458674fba (which includes #8419): with Ghidra 12.1.4 and Kuna 1.986 in separate SDK MCP sessions, I opened an owned Mach-O, resolved _evaluate, saved a snapshot, then opened a byte-identical copy under a different filename in a fresh session. list_documents and procedure_address succeeded against the new target. Ghidra explicitly marked the procedure result as snapshot replay; Kuna did not claim replay. The retained bundle still included the original record with its original path and a new result bound to the renamed target.

For Kuna, the old document path correctly failed after reopening; the new path worked. inspect_address_context for that stale path retained the same name-facet error as the direct address_name call, including the expected current document. For Ghidra the document identity stayed the same across these two fresh imports, so I instead tested a deliberately wrong document; context likewise preserved the direct error. Valid-document context returned the _evaluate name in both sessions. This is a positive control for the existing draft, not a new bug or proof of all relocation cases. Original and both copied target digests stayed unchanged; no target was executed. This tested a fresh server in the same process, not a process restart or arbitrary filesystem moves.

<!-- gh-comment-id:6552833343 --> @morluto commented on GitHub (Nov 1, 2026): Real-provider follow-up on draft #8426 stack `458674fba` (which includes #8419): with Ghidra 12.1.4 and Kuna 1.986 in separate SDK MCP sessions, I opened an owned Mach-O, resolved `_evaluate`, saved a snapshot, then opened a byte-identical copy under a different filename in a fresh session. `list_documents` and `procedure_address` succeeded against the new target. Ghidra explicitly marked the procedure result as snapshot replay; Kuna did not claim replay. The retained bundle still included the original record with its original path and a new result bound to the renamed target. For Kuna, the old document path correctly failed after reopening; the new path worked. `inspect_address_context` for that stale path retained the same name-facet error as the direct `address_name` call, including the expected current document. For Ghidra the document identity stayed the same across these two fresh imports, so I instead tested a deliberately wrong document; context likewise preserved the direct error. Valid-document context returned the `_evaluate` name in both sessions. This is a positive control for the existing draft, not a new bug or proof of all relocation cases. Original and both copied target digests stayed unchanged; no target was executed. This tested a fresh server in the same process, not a process restart or arbitrary filesystem moves.
Author
Owner

@BeqaKs commented on GitHub (Nov 3, 2026):

Closing as fixed on main by #8419 / #8417 (retain/preserve address context input errors). The issue stayed open because those PRs referenced rather than closed it.

<!-- gh-comment-id:6599991749 --> @BeqaKs commented on GitHub (Nov 3, 2026): Closing as fixed on main by #8419 / #8417 (retain/preserve address context input errors). The issue stayed open because those PRs referenced rather than closed it.
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#6594
No description provided.