[GH-ISSUE #3556] [Bug] rea update reports success without exposing an unavailable Frida native binding #1321

Open
opened 2026-10-16 21:04:15 +00:00 by bsakaguchi · 1 comment
Owner

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

Before submitting

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

Observed behavior

Updating an isolated global installation from REA 6.4.0 to 6.5.0 reports a successful, verified upgrade and tells the user to restart their agents, but leaves the newly introduced Frida dependency unable to load its native binding. The update result contains neither the unavailable provider state nor a recovery action. Running list-frida-devices --json immediately afterward exits with a provider-unavailable error caused by the missing binding.

The CLI version upgrade itself succeeds. The bug is that its success report provides no indication that an optional provider shipped with the new release is unusable. A user following the returned restart instruction has no reason to repair the installation until a later Frida command fails.

Area: Setup, packaging, or upgrade. Interface: CLI. Earliest observable stage: Setup or provider admission, at post-install verification and reporting.

Reproduction

These steps were executed against the published npm packages, using a dedicated global prefix. The path below is shortened for readability; the prefix and npm_config_prefix must refer to the same isolated directory. No ordinary global installation is required.

$prefix = Join-Path $env:TEMP 'rea-update-frida-repro'
npm.cmd install --global --ignore-scripts --prefix $prefix rea-agents@6.4.0 --no-audit --no-fund

# Select the isolated installation for this PowerShell process only.
$env:npm_config_prefix = $prefix
$entry = Join-Path $prefix 'node_modules/rea-agents/scripts/rea.mjs'
node $entry update --json
node $entry list-frida-devices --json

$binding = Join-Path $prefix 'node_modules/rea-agents/node_modules/frida/build/frida_binding.node'
Test-Path $binding

The published-package reproduction was run on Windows x64 with Node.js 24.11.1 and npm 11.6.2, when the registry's latest REA release was 6.5.0. A future registry release can change which version rea update selects, so the observed transition here is specifically 6.4.0 → 6.5.0. REA 6.4.0 has no Frida optional dependency; using --ignore-scripts for the starting installation does not suppress a preexisting Frida install in that release.

The initial installation succeeded. The installed 6.4.0 dispatcher then performed the actual update and exited 0. Its result, with only the local prefix abbreviated, was:

{
  "status": "updated",
  "previousVersion": "6.4.0",
  "latestVersion": "6.5.0",
  "installedVersion": "6.5.0",
  "installMethod": "npm",
  "command": [
    "npm", "install", "--global", "--ignore-scripts",
    "--prefix", "<isolated-prefix>", "rea-agents@6.5.0"
  ],
  "maintenance": { "status": "current", "plannedActions": [] },
  "remediation": "REA is updated. Restart agents running this installation to load the new version."
}

The subsequent list-frida-devices --json exited 1, reporting capability_unavailable / unsupported_provider. Its diagnostic began:

Could not locate the bindings file. Tried:
 → <isolated-prefix>/node_modules/rea-agents/node_modules/frida/build/frida_binding.node
 → <isolated-prefix>/node_modules/rea-agents/frida_binding.node

Test-Path returned False. The installed Frida package's manifest reported version 17.23.2. A separate dependency-only installation with scripts ignored also failed at import("frida") with the same binding error, confirming the failure before device discovery or target interaction.

Expected behavior and recovery contract

rea update should distinguish a verified CLI update from optional native-provider readiness. A successful package/version update can remain status: "updated" with exit 0 while explicitly reporting that Frida could not load, why it could not load, and what the user can do next. This avoids turning an optional capability failure into a failed core update.

The same information should be available in human and JSON output. Rerunning rea update on an already-current installation should check readiness again, so it can confirm a repair without reinstalling the same release. An inability to run or interpret the probe should remain an unknown result, rather than being reported as a missing native binding.

Recovery needs to identify the actual installation and resolved Frida package. A generic instruction to rebuild an unrelated global package or use the caller's project would be misleading, especially when dependencies are hoisted. A manually invoked command scoped to the resolved Frida directory can make the required download/build step explicit. The updater should not execute that repair automatically.

Analysis supported by source and package contents

The producing boundary is updateInstallCommand: both npm and Bun update commands include --ignore-scripts. systemUpdateHost verifies the installed entry point with --version, which establishes the CLI version but does not load optional native dependencies.

The Frida 17.23.2 tarball does not include build/frida_binding.node. Its install script acquires a prebuilt binding or invokes a build fallback. REA loads Frida lazily in FridaInstrumentationManager, so rea --version can pass while importing Frida fails. Frida declares N-API v8; the evidence here points to the skipped installation step rather than establishing a Node 24 ABI incompatibility.

Keeping lifecycle scripts disabled during an unattended update is a deliberate boundary worth preserving. This report does not propose enabling every dependency's install scripts. A focused remedy is to probe the newly installed module in a fresh process, preserve its actual load diagnostic, and offer a scoped, opt-in repair command.

Impact, scope, and remaining uncertainty

The observed impact is a successful 6.4.0 → 6.5.0 npm update followed by an unusable Frida provider and no update-time explanation. This affects the first use of Frida after that transition; unrelated CLI functionality can continue to work. No evidence corruption or target mutation was observed.

The equivalent Bun risk is source-derived from its --ignore-scripts update command, not a reproduced Bun installation. Whether an update replaces an already-working binding in another installation layout is also unverified. This report does not claim successful real-device discovery or instrumentation, or that every normal installation would succeed on this host. The tested failure occurs at module loading and requires no target binary, attached process, device, Hopper, or Ghidra.

The audit searched open and closed Issue/PR records for Frida, updates, ignore-scripts, and native bindings and found no matching update-readiness report or claimed fix. Historical #292 concerns removing PTY install-hook dependence; Frida support arrived later in #1359. They explain the lifecycle-script context but do not address this post-update reporting gap.

Implementation

The accompanying fix is available in https://github.com/morluto/rea/pull/3557, from the dedicated fix/update-optional-native-readiness branch. The PR is a draft pending the author's final review and readiness declaration.

Originally created by @dakjdakd on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3556 ## 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. ## Observed behavior Updating an isolated global installation from REA 6.4.0 to 6.5.0 reports a successful, verified upgrade and tells the user to restart their agents, but leaves the newly introduced Frida dependency unable to load its native binding. The update result contains neither the unavailable provider state nor a recovery action. Running `list-frida-devices --json` immediately afterward exits with a provider-unavailable error caused by the missing binding. The CLI version upgrade itself succeeds. The bug is that its success report provides no indication that an optional provider shipped with the new release is unusable. A user following the returned restart instruction has no reason to repair the installation until a later Frida command fails. **Area:** Setup, packaging, or upgrade. **Interface:** CLI. **Earliest observable stage:** Setup or provider admission, at post-install verification and reporting. ## Reproduction These steps were executed against the published npm packages, using a dedicated global prefix. The path below is shortened for readability; the prefix and `npm_config_prefix` must refer to the same isolated directory. No ordinary global installation is required. ```powershell $prefix = Join-Path $env:TEMP 'rea-update-frida-repro' npm.cmd install --global --ignore-scripts --prefix $prefix rea-agents@6.4.0 --no-audit --no-fund # Select the isolated installation for this PowerShell process only. $env:npm_config_prefix = $prefix $entry = Join-Path $prefix 'node_modules/rea-agents/scripts/rea.mjs' node $entry update --json node $entry list-frida-devices --json $binding = Join-Path $prefix 'node_modules/rea-agents/node_modules/frida/build/frida_binding.node' Test-Path $binding ``` The published-package reproduction was run on Windows x64 with Node.js 24.11.1 and npm 11.6.2, when the registry's latest REA release was 6.5.0. A future registry release can change which version `rea update` selects, so the observed transition here is specifically **6.4.0 → 6.5.0**. REA 6.4.0 has no Frida optional dependency; using `--ignore-scripts` for the starting installation does not suppress a preexisting Frida install in that release. The initial installation succeeded. The installed 6.4.0 dispatcher then performed the actual update and exited 0. Its result, with only the local prefix abbreviated, was: ```json { "status": "updated", "previousVersion": "6.4.0", "latestVersion": "6.5.0", "installedVersion": "6.5.0", "installMethod": "npm", "command": [ "npm", "install", "--global", "--ignore-scripts", "--prefix", "<isolated-prefix>", "rea-agents@6.5.0" ], "maintenance": { "status": "current", "plannedActions": [] }, "remediation": "REA is updated. Restart agents running this installation to load the new version." } ``` The subsequent `list-frida-devices --json` exited **1**, reporting `capability_unavailable` / `unsupported_provider`. Its diagnostic began: ```text Could not locate the bindings file. Tried: → <isolated-prefix>/node_modules/rea-agents/node_modules/frida/build/frida_binding.node → <isolated-prefix>/node_modules/rea-agents/frida_binding.node ``` `Test-Path` returned `False`. The installed Frida package's manifest reported version **17.23.2**. A separate dependency-only installation with scripts ignored also failed at `import("frida")` with the same binding error, confirming the failure before device discovery or target interaction. ## Expected behavior and recovery contract `rea update` should distinguish a verified CLI update from optional native-provider readiness. A successful package/version update can remain `status: "updated"` with exit 0 while explicitly reporting that Frida could not load, why it could not load, and what the user can do next. This avoids turning an optional capability failure into a failed core update. The same information should be available in human and JSON output. Rerunning `rea update` on an already-current installation should check readiness again, so it can confirm a repair without reinstalling the same release. An inability to run or interpret the probe should remain an unknown result, rather than being reported as a missing native binding. Recovery needs to identify the actual installation and resolved Frida package. A generic instruction to rebuild an unrelated global package or use the caller's project would be misleading, especially when dependencies are hoisted. A manually invoked command scoped to the resolved Frida directory can make the required download/build step explicit. The updater should not execute that repair automatically. ## Analysis supported by source and package contents The producing boundary is [`updateInstallCommand`](https://github.com/morluto/rea/blob/ca1b2f8608c52ed721d3576ba5eeb1d66717b08c/src/application/Update.ts): both npm and Bun update commands include `--ignore-scripts`. [`systemUpdateHost`](https://github.com/morluto/rea/blob/ca1b2f8608c52ed721d3576ba5eeb1d66717b08c/src/application/UpdateRuntime.ts) verifies the installed entry point with `--version`, which establishes the CLI version but does not load optional native dependencies. The Frida 17.23.2 tarball does not include `build/frida_binding.node`. Its install script acquires a prebuilt binding or invokes a build fallback. REA loads Frida lazily in `FridaInstrumentationManager`, so `rea --version` can pass while importing Frida fails. Frida declares N-API v8; the evidence here points to the skipped installation step rather than establishing a Node 24 ABI incompatibility. Keeping lifecycle scripts disabled during an unattended update is a deliberate boundary worth preserving. This report does **not** propose enabling every dependency's install scripts. A focused remedy is to probe the newly installed module in a fresh process, preserve its actual load diagnostic, and offer a scoped, opt-in repair command. ## Impact, scope, and remaining uncertainty The observed impact is a successful 6.4.0 → 6.5.0 npm update followed by an unusable Frida provider and no update-time explanation. This affects the first use of Frida after that transition; unrelated CLI functionality can continue to work. No evidence corruption or target mutation was observed. The equivalent Bun risk is source-derived from its `--ignore-scripts` update command, not a reproduced Bun installation. Whether an update replaces an already-working binding in another installation layout is also unverified. This report does not claim successful real-device discovery or instrumentation, or that every normal installation would succeed on this host. The tested failure occurs at module loading and requires no target binary, attached process, device, Hopper, or Ghidra. ## Related work and duplicate search The audit searched open and closed Issue/PR records for Frida, updates, `ignore-scripts`, and native bindings and found no matching update-readiness report or claimed fix. Historical [#292](https://github.com/morluto/rea/pull/292) concerns removing PTY install-hook dependence; Frida support arrived later in [#1359](https://github.com/morluto/rea/pull/1359). They explain the lifecycle-script context but do not address this post-update reporting gap. ## Implementation The accompanying fix is available in https://github.com/morluto/rea/pull/3557, from the dedicated `fix/update-optional-native-readiness` branch. The PR is a draft pending the author's final review and readiness declaration.
Author
Owner

@kaoru0822-kitauji commented on GitHub (Oct 25, 2026):

Still reproduces on the 6.7.0 → 6.8.0 update path (macOS 26.7.1 arm64, Node 24.22.1, npm 11.19.1, throwaway HOME and npm prefix):

  1. npm install --global rea-agents@6.7.0. npm 11.19 already skips frida's install script here: npm warn install-scripts … frida@17.23.2 (install: node scripts/install.js) (not yet covered by allowScripts).
  2. rea update → status: updated, installedVersion: 6.8.0, using the command npm install --global --ignore-scripts --prefix … rea-agents@6.8.0.
  3. <prefix>/lib/node_modules/rea-agents/node_modules/frida/build/frida_binding.node is absent. (A fresh npx -y rea-agents@6.8.0 cache does have it.)
  4. rea doctor stays silent about Frida: its checks are node, host, hopper, ghidra, ida-registration, jadx, kuna-installation.
  5. rea list-frida-devices --format json:
{"code":"capability_unavailable","category":"unsupported_provider","message":"This analysis is unavailable for the current target. Choose another analysis or target.", "details":{"provider_id":"frida","operation":"list_frida_devices","reason":"Could not locate the bindings file. Tried: → …/frida/build/frida_binding.node …"}}

The top-level message blames the target, but this operation has no target; the real cause is only in details.reason. The 6.8.0 updater (dist/application/Update.js) still passes --ignore-scripts.

<!-- gh-comment-id:6396263283 --> @kaoru0822-kitauji commented on GitHub (Oct 25, 2026): Still reproduces on the 6.7.0 → 6.8.0 update path (macOS 26.7.1 arm64, Node 24.22.1, npm 11.19.1, throwaway `HOME` and npm prefix): 1. `npm install --global rea-agents@6.7.0`. npm 11.19 already skips frida's install script here: `npm warn install-scripts … frida@17.23.2 (install: node scripts/install.js)` (not yet covered by `allowScripts`). 2. `rea update` → `status: updated`, `installedVersion: 6.8.0`, using the command `npm install --global --ignore-scripts --prefix … rea-agents@6.8.0`. 3. `<prefix>/lib/node_modules/rea-agents/node_modules/frida/build/frida_binding.node` is absent. (A fresh `npx -y rea-agents@6.8.0` cache does have it.) 4. `rea doctor` stays silent about Frida: its checks are `node, host, hopper, ghidra, ida-registration, jadx, kuna-installation`. 5. `rea list-frida-devices --format json`: ```json {"code":"capability_unavailable","category":"unsupported_provider","message":"This analysis is unavailable for the current target. Choose another analysis or target.", "details":{"provider_id":"frida","operation":"list_frida_devices","reason":"Could not locate the bindings file. Tried: → …/frida/build/frida_binding.node …"}} ``` The top-level message blames the target, but this operation has no target; the real cause is only in `details.reason`. The 6.8.0 updater (`dist/application/Update.js`) still passes `--ignore-scripts`.
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#1321
No description provided.