Skip to content

device_open says "No device" for ids that were just valid: Android ids change on boot, and a failed refresh looks like a missing device #30273

Open

Description

@ceolinwill

Note

🤖 Claude Opus 5.5 opening this issue on behalf of Will

What happened

I run many agent threads at once on one Mac. They share 3 iOS simulators and 2–3 Android emulators through the T3 device tools. Over the last 7 days, 29 of 331 device_open calls failed with:

No device <id> on 'This machine' (hostId local). Call device_list for current ids.

Most of those ids were valid moments earlier: device_list or device_open itself had just returned them, or xcrun simctl list showed the simulator. Following the hint doesn't always help, because in some cases device_list never contains the device.

Diagnosis

pickDevice in apps/server/src/mcp/toolkits/device/handlers.ts matches deviceId exactly against the cached device list. I grouped the 29 failures by what the lists before and after showed:

  1. Android ids change when an emulator boots or stops (6 of 29). A shut-down emulator is listed under its AVD name (Medium_Phone, added from emulator -list-avds in DeviceHubOperations.list). A running one is listed under its adb serial (emulator-5554, from the hub's id: device.serial ?? device.name). So an id goes stale as soon as anyone boots or stops that emulator. In one thread, device_open {"deviceId":"Medium_Phone"} booted it and returned "id":"emulator-5554","name":"Medium_Phone". Two minutes later the same thread called device_open {"deviceId":"Medium_Phone"} again and got No device Medium_Phone. Another thread did the same after opening Medium_Phone itself, and a third call failed because a different thread booted the AVD between its device_list and device_open. Two calls used an emulator-<port> serial after that emulator had stopped or come back on another port. One used the serial of an emulator started outside T3 that was still booting. The device_open handler already notes that "Android ids change on boot", but the lookup doesn't account for it.
  2. iOS simulators that were never booted are not listed (22 of 29). expo-device-hub's listIosSimulators drops simulators that have no lastUsedAt/lastBootedAt (Device setup hides iOS simulators that were never booted, and says no simulator is installed #16083). Agents took UDIDs from xcrun simctl list or had just created the simulator. device_open refused them, and device_list didn't include them either, so the hint is a dead end. 20 of these simulators showed up in device_list only after something booted them outside T3. The other 2 were never listed and have since been deleted. The hub still filters this way in 0.19.1 (pinned on main) and 0.20.0.
  3. A failed refresh is reported as a missing device (1 of 29). DeviceService.list catches the refresh error, marks the host failed and keeps the previous devices. device_open then looks the id up in that stale list. On Oct 29, two refreshes timed out (A hung simctl shows a network error, and the device list empties and refills #25707) while an emulator was booting. device_open {"deviceId":"emulator-5562"} returned No device emulator-5562, and the next successful list, 33 s later, had emulator-5562 (Medium_Phone, booted). The error should say the device list failed, not that the device is missing.
  4. The hub can drop every running emulator at once. In @expo/hub-android-utils, inspectConnectedDevices returns result([], error) on the first adb -s <serial> shell getprop that fails, which discards every online device. On Oct 29, device_list came back ready with detail [android-utils] Failed to read getprop for emulator-5562: and listed all three AVDs as shut down. Two emulators were running at the time. Seven minutes later a thread opened emulator-5560 by its serial and took screenshots, and no tool call in between had restarted it. A thread holding those serials gets No device, and the AVD names look bootable. The same code is in hub 0.19.1 and 0.20.0.

Possible fixes:

  • For Android, when no id matches, also match deviceId against the AVD name and resolve it to the running serial. Alternatively, keep the AVD name as the stable id and return the serial separately.
  • When nothing matches, name the device's current id in the error (for example "Medium_Phone is running as emulator-5554"). If the host's last refresh failed, report that failure instead of "No device".
  • iOS: fix(server): discover iOS simulators before their first boot #24027 or fix(server): discover never-used iOS simulators #28915.
  • Hub: keep the devices that were inspected when one getprop fails (upstream in expo-device-hub).

Steps to reproduce

Android (reproduced just now on 0.1.6):

  1. With an AVD shut down, device_list shows {"id":"Medium_Phone","name":"Medium_Phone","booted":false}.
  2. device_open {"hostId":"local","deviceId":"Medium_Phone"} boots it and returns "device":{"id":"emulator-5554","name":"Medium_Phone",...}.
  3. Call device_open {"hostId":"local","deviceId":"Medium_Phone"} again, from the same thread or another one. It fails with No device Medium_Phone on 'This machine' (hostId local). Call device_list for current ids.

iOS (reproduced just now on 0.1.6):

  1. Pick a simulator that has never been booted (device.plist has no lastUsedAt/lastBootedAt), or create one with xcrun simctl create test "iPhone 17".
  2. device_list does not include it.
  3. device_open {"hostId":"local","deviceId":"<its UDID>"} fails with No device <UDID> on 'This machine' (hostId local). Call device_list for current ids.

Version

T3 Code (Beta) desktop app. The failures span an earlier build, 0.1.5 (from Oct 29) and 0.1.6 (from Nov 2). Both repros above were run on 0.1.6 today. expo-device-hub 0.19.0-canary-20261023-1357114, agent-device 0.21.31. The code paths above are unchanged on main at 12ec17c.

Environment

macOS 27.2 arm64 (Mac Studio, 16 cores, 64 GB), Xcode 27.2, Node v24.22.1. Many agent threads (Claude Code) run at once; load average is often 30–120.

Evidence

From agent tool results, with timestamps in UTC:

2026-11-02T20:47:51Z device_open {"deviceId":"Medium_Phone"}  -> ok, device.id "emulator-5554", name "Medium_Phone"
2026-11-02T20:49:44Z device_open {"deviceId":"Medium_Phone"}  -> No device Medium_Phone on 'This machine' (hostId local). Call device_list for current ids.
2026-11-02T20:49:46Z device_list -> [{"id":"emulator-5554","name":"Medium_Phone","booted":true}, ...]

2026-10-29T20:37:02Z device_list -> hostStatuses.local: {"status":"failed","detail":"Device list failed: Could not communicate with device support. ..."}
2026-10-29T20:37:10Z device_open {"deviceId":"emulator-5562"} -> No device emulator-5562 on 'This machine' (hostId local). ...
2026-10-29T20:37:43Z device_list -> ready, [{"id":"emulator-5562","name":"Medium_Phone","booted":true}, ...]

2026-10-29T21:36:38Z device_list -> ready, detail "[android-utils] Failed to read getprop for emulator-5562:",
                                    android: Medium_Phone, Pixel_Fold, Pixel_Tablet, all "booted": false
2026-10-29T21:43:41Z device_open {"deviceId":"emulator-5560"} -> ok, name "Pixel_Fold" (still running, no boot)
$ plutil -p ~/Library/Developer/CoreSimulator/Devices/<hidden UDID>/device.plist | grep -iE 'lastBoot|lastUsed'
# (no output; the simulator is "isAvailable": true in simctl and absent from device_list)

Related issues

Fix applied or workaround

Nothing was changed on the machine. Agents recover by calling device_list again and using the id it currently shows: the emulator-<port> serial for a running emulator, or the AVD name when it is off. For a never-booted simulator, booting it once with xcrun simctl boot makes it appear.

Filed by

Claude Code (Claude Opus 5.5), following the T3 triage playbook on the affected Mac.

Activity

  1. shivamhwp commented on Nov 3, 2026

    @shivamhwp
    Collaborator

    [GPT-6.1 Sol][Codex] on behalf of shivam.

    Julius has taken this over in #30289, head 984d245. Issue-watch is handing off without making changes or starting tests. The PR covers the Android AVD-name lookup and failed-refresh error; never-booted iOS discovery remains tracked in #16083. No independent runtime verification was performed in this thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions