[GH-ISSUE #5232] [Bug] Frida one-shot cancellation discards a native resume failure #3204

Closed
opened 2026-10-31 00:37:48 +00:00 by bsakaguchi · 1 comment
Owner

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

Before submitting

  • I searched open and closed issues for a related report.
  • I removed credentials and sensitive target data.

Area

Process capture or runtime observation

Observed behavior

The shared Frida one-shot service replaces an ordinary provider resume failure with cancellation when the caller aborts before the resume result settles. A controlled service regression reproduces this for both successful and failed session cleanup. No native target or Frida binding ran.

Reproduction

Executed a focused regression in src/application/frida/FridaInstrumentationService.test.ts against main 2ec602b191d3b36dd17733e3e183457c57651c60 on pinned Node 24.18.0:

  1. Call FridaInstrumentationService.instrument with spawn mode, program /fixture, explicit local device, inline marker script, duration zero and a signal.
  2. Inject a provider returning a paused session and successful script load. Hold its resumeSession result behind an explicit entry/settlement barrier.
  3. After resume enters, abort the caller with an explicit Error, then settle resume with a stable AnalysisCapabilityUnavailableError carrying diagnostic native_status: resume_rejected.
  4. Let session close either succeed or fail; inspect the returned service Result. Both cases return AnalysisCancelledError, losing the primary provider error. A provider-typed cancellation control remains cancellation.

Command actually run: npm run test:local -- src/application/frida/FridaInstrumentationService.test.ts. Result: 2 failed,26 passed; both failures are the native resume-failure controls. The forthcoming fix includes these fixtures. This is a controlled application-boundary reproduction, not an executed public CLI/MCP or real-provider scenario.

Expected behavior

Preserve the ordinary provider failure, its diagnostics, and any cleanup failure. The lifecycle contract says to preserve an existing primary failure when considering later cancellation. Successful resume followed by cancellation and provider-typed cancellation should remain cancellation.

Impact and scope

The bounded ordering loses the native failure classification and diagnostic. Both controlled cleanup outcomes reproduce it once in this run. Real-provider frequency, target effects, and public-adapter output are NOT_ENOUGH_INFO; those were not exercised. No target safety consequence or general workflow outage is claimed.

REA version

Source package 6.7.0, main 2ec602b191d3b36dd17733e3e183457c57651c60.

Runtime and platform

Node 24.18.0, macOS 26.3, arm64.

Target and artifact context

Synthetic service port; no real target, remote endpoint or injected code execution.

Interface

Other: shared application service used by CLI/MCP.

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

Both cases fail the assertion that the returned error is not AnalysisCancelledError:

preserves a native resume failure ... (cleanupFails=false): FAILED
preserves a native resume failure ... (cleanupFails=true): FAILED
expected Error: Analysis operation was cancelled ... to not be an instance of AnalysisCancelledError
Tests 2 failed | 26 passed (28)

Source explanation: instrument checks signal.aborted immediately after awaiting resume and only later checks the returned failure. Thus the actual provider Result is discarded. The manager can return an ordinary provider error after an in-flight native rejection; that scheduling is source-derived, not a real-provider reproduction here.

Typed outcome or recovery expected

Original provider error when close succeeds; existing cleanup composition retaining that error and diagnostics when close fails. Preserve typed cancellation controls and close exactly once.

Additional context

Found while auditing nearby consumers for #5082. That report concerns cancellation during final detach after successful observation; this one concerns precedence of an already-returned resume failure. Search found no duplicate report; lifecycle tracker #4227 is broader.

Originally created by @morluto on GitHub (Oct 19, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5232 ### Before submitting - [x] I searched open and closed issues for a related report. - [x] I removed credentials and sensitive target data. ### Area Process capture or runtime observation ### Observed behavior The shared Frida one-shot service replaces an ordinary provider resume failure with cancellation when the caller aborts before the resume result settles. A controlled service regression reproduces this for both successful and failed session cleanup. No native target or Frida binding ran. ### Reproduction Executed a focused regression in `src/application/frida/FridaInstrumentationService.test.ts` against main `2ec602b191d3b36dd17733e3e183457c57651c60` on pinned Node 24.18.0: 1. Call `FridaInstrumentationService.instrument` with spawn mode, program `/fixture`, explicit local device, inline marker script, duration zero and a signal. 2. Inject a provider returning a paused session and successful script load. Hold its `resumeSession` result behind an explicit entry/settlement barrier. 3. After resume enters, abort the caller with an explicit Error, then settle resume with a stable `AnalysisCapabilityUnavailableError` carrying diagnostic `native_status: resume_rejected`. 4. Let session close either succeed or fail; inspect the returned service Result. Both cases return `AnalysisCancelledError`, losing the primary provider error. A provider-typed cancellation control remains cancellation. Command actually run: `npm run test:local -- src/application/frida/FridaInstrumentationService.test.ts`. Result: 2 failed,26 passed; both failures are the native resume-failure controls. The forthcoming fix includes these fixtures. This is a controlled application-boundary reproduction, not an executed public CLI/MCP or real-provider scenario. ### Expected behavior Preserve the ordinary provider failure, its diagnostics, and any cleanup failure. The [lifecycle contract](https://github.com/morluto/rea/blob/2ec602b191d3b36dd17733e3e183457c57651c60/docs/tool-design.md#own-the-lifecycle) says to preserve an existing primary failure when considering later cancellation. Successful resume followed by cancellation and provider-typed cancellation should remain cancellation. ### Impact and scope The bounded ordering loses the native failure classification and diagnostic. Both controlled cleanup outcomes reproduce it once in this run. Real-provider frequency, target effects, and public-adapter output are NOT_ENOUGH_INFO; those were not exercised. No target safety consequence or general workflow outage is claimed. ### REA version Source package 6.7.0, main `2ec602b191d3b36dd17733e3e183457c57651c60`. ### Runtime and platform Node 24.18.0, macOS 26.3, arm64. ### Target and artifact context Synthetic service port; no real target, remote endpoint or injected code execution. ### Interface Other: shared application service used by CLI/MCP. ### Earliest failure stage Cleanup, cancellation, or lifecycle ### Relevant output or evidence Both cases fail the assertion that the returned error is not AnalysisCancelledError: ```text preserves a native resume failure ... (cleanupFails=false): FAILED preserves a native resume failure ... (cleanupFails=true): FAILED expected Error: Analysis operation was cancelled ... to not be an instance of AnalysisCancelledError Tests 2 failed | 26 passed (28) ``` Source explanation: [instrument](https://github.com/morluto/rea/blob/2ec602b191d3b36dd17733e3e183457c57651c60/src/application/frida/FridaInstrumentationService.ts) checks `signal.aborted` immediately after awaiting resume and only later checks the returned failure. Thus the actual provider Result is discarded. The manager can return an ordinary provider error after an in-flight native rejection; that scheduling is source-derived, not a real-provider reproduction here. ### Typed outcome or recovery expected Original provider error when close succeeds; existing cleanup composition retaining that error and diagnostics when close fails. Preserve typed cancellation controls and close exactly once. ### Additional context Found while auditing nearby consumers for #5082. That report concerns cancellation during final detach after successful observation; this one concerns precedence of an already-returned resume failure. Search found no duplicate report; lifecycle tracker #4227 is broader.
bsakaguchi 2026-10-31 00:37:48 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

@morluto commented on GitHub (Oct 19, 2026):

Fixed on main in 69aa5465cd.

The application now inspects the settled resume Result before considering the caller signal. An ordinary provider failure retains its original identity/diagnostics when cleanup succeeds, or remains the cause of the existing cleanup aggregate when cleanup fails. Successful resume followed by cancellation and provider-typed cancellation still use the cancellation path; cleanup runs once.

Validation on pinned Node24.18.0: the application baseline reproduced2 failures/26 passes; after repair127 focused tests passed across5 files. Added registered MCP coverage then passed alongside the service suite (70 tests/2 files): a simulated native resume rejects only after the server-observed signal is aborted, and production manager/service/delivery retain the native error. Cleanup releases the script/session normally. Final check passed; unchanged manager/CLI/contract controls passed in the127-test run. Independent source review found no blocker.

This extends verification beyond the original application-only report, but all Frida native handles remain simulated. No real target/native scheduling frequency, persistent database behavior, Linux/Windows qualification, performance improvement or full audit completion is claimed.

<!-- gh-comment-id:6264999581 --> @morluto commented on GitHub (Oct 19, 2026): Fixed on main in 69aa5465cd77c5cf9ff435e7a5a322d90c1db12c. The application now inspects the settled resume Result before considering the caller signal. An ordinary provider failure retains its original identity/diagnostics when cleanup succeeds, or remains the cause of the existing cleanup aggregate when cleanup fails. Successful resume followed by cancellation and provider-typed cancellation still use the cancellation path; cleanup runs once. Validation on pinned Node24.18.0: the application baseline reproduced2 failures/26 passes; after repair127 focused tests passed across5 files. Added registered MCP coverage then passed alongside the service suite (70 tests/2 files): a simulated native resume rejects only after the server-observed signal is aborted, and production manager/service/delivery retain the native error. Cleanup releases the script/session normally. Final check passed; unchanged manager/CLI/contract controls passed in the127-test run. Independent source review found no blocker. This extends verification beyond the original application-only report, but all Frida native handles remain simulated. No real target/native scheduling frequency, persistent database behavior, Linux/Windows qualification, performance improvement or full audit completion is claimed.
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#3204
No description provided.