Skip to content

Multi-device routing + dev-client picker hangs (combined session feedback) #136

Description

@Lykhoyda

Description

Long testing session on a React Native app surfaced three rn-dev-agent friction points worth reporting together:

  1. Multi-device routing of device_screenshot — with both iOS sim and Android emulator booted, device_screenshot platform: "android" captured the iOS screen every time. Forced fallback to raw adb exec-out screencap -p for every Android screenshot in the session. (Re-evidence on existing IX-2950 session feedback: multi-device routing bugs + missing primitives (record/storage/reset) #60.)

  2. cdp_status "Already connecting to Metro" race against Expo dev-client picker — on dev-client builds, after launchApp/relaunch, cdp_status returned "Already connecting to Metro... Dev Client picker detected but could not find a server entry to tap. Select the Metro server manually." Two consecutive cdp_status calls hung 60s and 35s respectively (see telemetry below). The plugin sees the picker but doesn't auto-tap the single configured server, leaving the session blocked until manual intervention.

  3. No automatic dev-launcher handling in launchApp — the same picker issue surfaces for Maestro actions: every launchApp: { stopApp: true } on a dev-client build lands on the Expo "DEVELOPMENT SERVERS" picker instead of the welcome screen. Users have to write their own runFlow when: visible: "DEVELOPMENT SERVERS" block (which itself races the picker auto-advance — fails ~30% of the time).

Environment

Field Value
Plugin version 0.44.26
CDP Bridge 0.38.20
Tool count 74
OS Darwin 25.3.0
Node.js v24.14.0
npm 11.9.0
Metro running on 8081
iOS Simulators 1 booted
Android Emulators 0 connected (at collection time — Pixel 9 Pro was driven during session, emulator OOM-died mid-run)
agent-device 0.8.0
maestro-runner 1.0.9

Recent Tool Activity (telemetry excerpts)

ts tool result latency
12:49:58 maestro_run PASS 92422 ms
13:03:35 device_screenshot PASS 775 ms
13:07:23 device_screenshot PASS 904 ms
13:29:34 device_list PASS 1085 ms
13:37:49 cdp_status FAIL 60009 ms
13:38:39 cdp_status FAIL 34676 ms
13:38:44 device_screenshot PASS 1329 ms

The two cdp_status FAIL rows are the Metro-connection hangs.

Steps to Reproduce

Issue 1 — device_screenshot wrong platform

  1. Boot iOS simulator AND Android emulator simultaneously.
  2. Load the same app on both (e.g. pnpm android while iOS sim is also running).
  3. Call device_screenshot platform: "android".
  4. Actual: returns 1179×2556 image (iPhone 15 Pro resolution).
  5. Expected: returns 1280×2856 image (Pixel 9 Pro resolution).

Issue 2 — cdp_status hangs on dev-client picker

  1. Have a dev-client (Expo Dev Client) build installed.
  2. Run a Maestro action with launchApp: { stopApp: true, clearKeychain: true }.
  3. After action ends, app sits on the "DEVELOPMENT SERVERS" picker.
  4. Call cdp_status platform: "android" (or iOS).
  5. Actual: returns {"ok":false,"error":"Already connecting to Metro... Dev Client picker detected but could not find a server entry to tap. Select the Metro server manually."} after 30–60s timeout.
  6. Expected: plugin auto-taps the (single) configured server entry, then returns connected status.

Issue 3 — No auto-handler for dev-launcher in launchApp

  1. Same scenario as post-edit-health-check still fires when app is not installed/running on booted simulator #2.
  2. Maestro flows currently have to wrap the post-launch step in:
    - runFlow:
        when:
          visible:
            text: "DEVELOPMENT SERVERS"
        commands:
          - tapOn: { text: "http://" }
  3. The runFlow when: evaluates true, but the tapOn races against the picker's auto-advance — fails with "context deadline exceeded: WDA error: unable to find an element using 'predicate string', value '(label CONTAINS[c] 'http://' OR name CONTAINS[c] 'http://' OR value CONTAINS[c] 'http://')'".

Workaround

  1. Issue 1: raw adb -s <emu-id> exec-out screencap -p > out.png (Android) or xcrun simctl io <UDID> screenshot out.png (iOS).
  2. Issue 2: call cdp_status only after manually tapping the picker (defeats the auto-connect purpose).
  3. Issue 3: retry the action; works ~70% of the time. The picker race is unavoidable on dev-client builds.

Suggested Fix

  • Issue 1 / IX-2950 session feedback: multi-device routing bugs + missing primitives (record/storage/reset) #60: when platform: is passed, route device_screenshot through the platform-specific raw command (adb exec-out screencap for Android, xcrun simctl io for iOS) — bypass the WDA/UIAutomator2 ambiguity entirely.
  • Issue 2: in cdp_status Metro-connect path, detect "DEVELOPMENT SERVERS" via accessibility tree and auto-tap the single visible server entry before returning. Today the plugin already detects the picker (the error message proves it) — just needs to take action.
  • Issue 3: launchApp (or a new dev_client_unblock MCP tool) should bake in the picker-tap when the dev launcher is detected after launch, with a deterministic wait-and-retry instead of the runFlow race.

Related Issues

Side Observations (Not Blocking, FYI)

  • rn-collect-feedback reported android_emulators: 0 connected even though Pixel 9 Pro was used during the session. Collector takes a single-moment snapshot, so emulator restarts/crashes within the session aren't reflected. Could note "see telemetry for actual device usage" or include device-events log.
  • Maestro action authoring lessons learned (point-based taps, OTP digit-race on CodeInput, MarketSelect handling) are user-side learnings — not plugin defects — but might be worth a "writing reliable .rn-agent/actions" docs page.

Submitted via /rn-dev-agent:send-feedback — data sanitized automatically

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions