[GH-ISSUE #3051] [Bug] list_adb_devices reports may_have_started_adb_server false after adb starts its server #1063

Closed
opened 2026-10-15 18:30:46 +00:00 by bsakaguchi · 0 comments
Owner

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

Before submitting

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

Area

Process capture or runtime observation

Observed behavior

When no adb server is running, list-adb-devices (MCP list_adb_devices) makes the adb client start its local server but returns may_have_started_adb_server: false. adb writes its daemon-start notices to stderr, and REA looks for them only in stdout, so the result omits the side effect that docs/adb-device-analysis.md says is recorded.

The call exits 0 and returns "devices": [] with "may_have_started_adb_server": false. Afterwards adb -L tcp:5037 fork-server server --reply-fd 4 is running. adb 34.0.5 (the build the docs name as verified) and adb 37.0.1 both put only List of devices attached on stdout. They write * daemon not running; starting now at tcp:5037 and * daemon started successfully to stderr.

Current main behaves the same. I called AdbProvider.execute({ operation: "list_adb_devices", input: {} }) from a scratch vitest file against the real adb binaries on a private server port (5199). It returned may_have_started_adb_server: false and left adb -L tcp:5199 fork-server server running.

Reproduction

  1. Make sure no adb server runs: adb kill-server, then pgrep -lf 'adb -L tcp:5037 fork-server' prints nothing.
  2. Run REA_ADB_PATH=/abs/path/to/platform-tools/adb npx -y rea-agents@6.4.0 list-adb-devices --json.
  3. Run pgrep -lf 'adb -L tcp:5037 fork-server' again. The server is now running.
  4. Optional, to see the streams: run adb kill-server, then adb devices -l > out.txt 2> err.txt and compare the two files.
  5. Optional, to avoid touching a server that other tools use: export ANDROID_ADB_SERVER_PORT set to an unused port (for example 5199) for steps 1-4 and use that port in the pgrep pattern. adb and the REA child process both honor it.

Control: if you run step 2 again while the server it started is still up, it also returns false, which is correct for that case.

Expected behavior

docs/adb-device-analysis.md (lines 10-11) says: "The adb client may start its local server on first device query; that is adb client behavior, recorded in the tool result when observed." In step 2 the query starts the server and adb reports it (* daemon started successfully), so the result should contain may_have_started_adb_server: true.

When a server is already running before the call, the result should still report false. Device parsing and the unrecognized-line refusal for stdout should keep their current behavior.

Impact and scope

Affected: list_adb_devices (CLI and MCP) on the first query against a cold adb server. The documented structured field reports no side effect while the call leaves a background adb server running. A caller that relies on the field to decide whether to clean up leaves the server behind.

Not affected: the device list itself is correct, and calls made while a server is already running report correctly.

Workaround: check for an adb server process on the selected port (for example pgrep -f 'adb -L tcp:5037 fork-server') before and after the call. Run adb kill-server only when the call started one, so you do not stop a server another tool was using.

REA version

6.4.0 (npm); also reproduced from source at main e049ef70f7

Runtime and platform

Node 26.10.0; macOS 27.0 arm64; Android SDK Platform-Tools r34.0.5 (adb 34.0.5-10900879) and r37.0.1 (adb 37.0.1-15733141)

Target and artifact context

No device or emulator attached; cold adb server

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

$ adb devices -l > out.txt 2> err.txt      # adb 34.0.5 and 37.0.1, no server running
out.txt:
List of devices attached

err.txt:
* daemon not running; starting now at tcp:5037
* daemon started successfully

$ REA_ADB_PATH=/abs/path/to/platform-tools/adb npx -y rea-agents@6.4.0 list-adb-devices --json   # no server running; exit 0
"normalized_result": {"client": {..., "version": "37.0.1-15733141"}, "devices": [], "may_have_started_adb_server": false}

$ pgrep -lf 'adb -L tcp:5037 fork-server'
<pid> adb -L tcp:5037 fork-server server --reply-fd 4

Analysis or suspected cause

Source-derived. parseAdbDevicesOutput in src/adb/AdbDeviceOutput.ts recognizes the * daemon ... started successfully line. However, the list_adb_devices branch in src/adb/AdbProvider.ts (line 711 on main, line 621 at tag rea-agents-6.4.0) passes it only ran.value.stdout, even though runAdb also captures stderr.

Since the tag, the list_adb_devices branch, the daemon-notice handling, and the docs sentence have not changed. The unit test lists devices with inferred kinds and observed daemon startup in src/adb/AdbProvider.test.ts expects true for these notices, but its stub prints them on stdout, which adb 34.0.5 and 37.0.1 do not do.

Additional context

The r37.0.1 zip matches the SHA-1 in Google's current SDK repository manifest. The r34.0.5 zip is no longer listed there. Both adb binaries carry a valid Google LLC Developer ID signature.

Originally created by @coygeek on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3051 ### 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 Process capture or runtime observation ### Observed behavior When no adb server is running, `list-adb-devices` (MCP `list_adb_devices`) makes the adb client start its local server but returns `may_have_started_adb_server: false`. adb writes its daemon-start notices to stderr, and REA looks for them only in stdout, so the result omits the side effect that `docs/adb-device-analysis.md` says is recorded. The call exits 0 and returns `"devices": []` with `"may_have_started_adb_server": false`. Afterwards `adb -L tcp:5037 fork-server server --reply-fd 4` is running. adb 34.0.5 (the build the docs name as verified) and adb 37.0.1 both put only `List of devices attached` on stdout. They write `* daemon not running; starting now at tcp:5037` and `* daemon started successfully` to stderr. Current `main` behaves the same. I called `AdbProvider.execute({ operation: "list_adb_devices", input: {} })` from a scratch vitest file against the real adb binaries on a private server port (5199). It returned `may_have_started_adb_server: false` and left `adb -L tcp:5199 fork-server server` running. ### Reproduction 1. Make sure no adb server runs: `adb kill-server`, then `pgrep -lf 'adb -L tcp:5037 fork-server'` prints nothing. 2. Run `REA_ADB_PATH=/abs/path/to/platform-tools/adb npx -y rea-agents@6.4.0 list-adb-devices --json`. 3. Run `pgrep -lf 'adb -L tcp:5037 fork-server'` again. The server is now running. 4. Optional, to see the streams: run `adb kill-server`, then `adb devices -l > out.txt 2> err.txt` and compare the two files. 5. Optional, to avoid touching a server that other tools use: export `ANDROID_ADB_SERVER_PORT` set to an unused port (for example 5199) for steps 1-4 and use that port in the `pgrep` pattern. adb and the REA child process both honor it. Control: if you run step 2 again while the server it started is still up, it also returns `false`, which is correct for that case. ### Expected behavior `docs/adb-device-analysis.md` (lines 10-11) says: "The adb client may start its local server on first device query; that is adb client behavior, recorded in the tool result when observed." In step 2 the query starts the server and adb reports it (`* daemon started successfully`), so the result should contain `may_have_started_adb_server: true`. When a server is already running before the call, the result should still report `false`. Device parsing and the unrecognized-line refusal for stdout should keep their current behavior. ### Impact and scope Affected: `list_adb_devices` (CLI and MCP) on the first query against a cold adb server. The documented structured field reports no side effect while the call leaves a background adb server running. A caller that relies on the field to decide whether to clean up leaves the server behind. Not affected: the device list itself is correct, and calls made while a server is already running report correctly. Workaround: check for an adb server process on the selected port (for example `pgrep -f 'adb -L tcp:5037 fork-server'`) before and after the call. Run `adb kill-server` only when the call started one, so you do not stop a server another tool was using. ### REA version 6.4.0 (npm); also reproduced from source at main e049ef70f71aeb9965e9d75d4d4a84ea02eaee11 ### Runtime and platform Node 26.10.0; macOS 27.0 arm64; Android SDK Platform-Tools r34.0.5 (adb 34.0.5-10900879) and r37.0.1 (adb 37.0.1-15733141) ### Target and artifact context No device or emulator attached; cold adb server ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence ```text $ adb devices -l > out.txt 2> err.txt # adb 34.0.5 and 37.0.1, no server running out.txt: List of devices attached err.txt: * daemon not running; starting now at tcp:5037 * daemon started successfully $ REA_ADB_PATH=/abs/path/to/platform-tools/adb npx -y rea-agents@6.4.0 list-adb-devices --json # no server running; exit 0 "normalized_result": {"client": {..., "version": "37.0.1-15733141"}, "devices": [], "may_have_started_adb_server": false} $ pgrep -lf 'adb -L tcp:5037 fork-server' <pid> adb -L tcp:5037 fork-server server --reply-fd 4 ``` ### Analysis or suspected cause Source-derived. `parseAdbDevicesOutput` in `src/adb/AdbDeviceOutput.ts` recognizes the `* daemon ... started successfully` line. However, the `list_adb_devices` branch in `src/adb/AdbProvider.ts` (line 711 on `main`, line 621 at tag `rea-agents-6.4.0`) passes it only `ran.value.stdout`, even though `runAdb` also captures `stderr`. Since the tag, the `list_adb_devices` branch, the daemon-notice handling, and the docs sentence have not changed. The unit test `lists devices with inferred kinds and observed daemon startup` in `src/adb/AdbProvider.test.ts` expects `true` for these notices, but its stub prints them on stdout, which adb 34.0.5 and 37.0.1 do not do. ### Additional context The r37.0.1 zip matches the SHA-1 in Google's current SDK repository manifest. The r34.0.5 zip is no longer listed there. Both adb binaries carry a valid Google LLC Developer ID signature.
bsakaguchi 2026-10-15 18:30:46 +00:00
  • closed this issue
  • added the
    bug
    label
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#1063
No description provided.