Skip to content

A hung simctl shows a network error, and the device list empties and refills #25707

Closed

Description

@Jacksondr5

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

Server and web: Device panel and onboarding, local device host (macOS)

Steps to reproduce

This happened on my Mac when CoreSimulatorService stopped answering after about two days of uptime: every xcrun simctl call hung, including simctl help. To reproduce it without waiting for that, pause the service and resume it afterwards:

  1. Quit Simulator.app. Find the service with launchctl list | grep -i coresimulator, then kill -STOP <pid>.
  2. On macOS, start a dev server and open the Device panel. Click Refresh devices a few times.
  3. Resume with kill -CONT <pid>.

For the case where simctl fails at once rather than hanging, I put a fake xcrun first on the dev server's PATH that exits 1 with CoreSimulator's error. (The server rebuilds PATH from the login shell in fixPath, so the test server also needs SHELL pointed at a wrapper that prepends it.)

Reproduced on main at d487078f11 (the paused service) and 90c455ff8f (the fake failure), macOS 27.0.1.

Expected behavior

The panel says the simulator service isn't answering, and keeps showing the devices it last found while it can't list them.

Actual behavior

When simctl hangs:

  • After 15 s the panel shows "Device list failed: Could not communicate with device support. Try refreshing devices. Check the host connection and network access, then retry." Nothing points at the simulator service, and the network advice points the wrong way. hubJson (apps/server/src/device/DeviceHubOperations.ts:61) gives up after 15 s and maps a timeout, a bad status and a decode failure all to request_failed (packages/contracts/src/device.ts:523).
  • Each refresh shows the old list again, then replaces it with the error card when it fails 15 s later.
  • Each refresh leaves another stuck xcrun simctl list devices --json under the device hub (1 → 2 → 3 in my test). They clear once the service recovers.

When simctl fails at once:

  • The hub answers with simulators: [] and an errors entry, and refresh in DeviceService.ts (around line 402) replaces the host's devices with the empty list. The panel says "No simulators or emulators were found" until a refresh succeeds and brings them all back.
  • Onboarding's "Check simulator support" step says "Xcode is installed, but no iOS Simulator is available. Install a runtime in Xcode Settings → Components." (apps/web/src/components/device/DeviceSetup.tsx:110). That points at the wrong fix: the runtimes are installed, and the service isn't answering.

Impact

Minor bug or occasional failure. The fix for the person is restarting CoreSimulatorService, but nothing says so.

Related work

Possible fix

  • If Add file-backed appearance config for font overrides #464 lands with 30 s, T3's device-list timeout needs to be longer than that (for example 35–40 s), so the hub's timeout error reaches the panel instead of T3 giving up first at 15 s. T3 pins expo-device-hub canaries from Expo's main, so a canary bump after Add file-backed appearance config for font overrides #464 merges would pick it up.
  • A distinct timeout message in hubJson, such as "The device hub did not answer within N s", for hubs without Add file-backed appearance config for font overrides #464 or anything else that stops the hub answering.
  • Keep the last known devices when the hub's list comes back empty with errors, and show the errors as the warning. This is a product choice, so I'd like your view before sending it.
  • The onboarding hint could say the simulator service isn't responding when the hub reports a simctl error, rather than suggesting a missing runtime.

I'm happy to send a PR for the timeout and the message once you've said which of these you want.

Posted by Claude Opus 5.5, an AI agent, on Jackson's behalf.

Activity

  1. MarcinusX commented on Oct 30, 2026

    @MarcinusX

    Another case with the same symptom, this time caused by host load rather than a hung simctl (T3 Code Desktop 0.1.6-nightly.20261030.3917, macOS 27.2 arm64).

    • Load average was ~220 on 10 cores: parallel Playwright browser sweeps from an agent thread, plus normal desktop apps.
    • GET /api/devices on expo-device-hub 0.19.0-canary-20261023 returned a correct 200 after 56.6 s. xcrun simctl list devices -j took 6.8 s. No simctl processes were stuck.
    • Every DeviceHubOperations.list call failed with TimeoutError: Operation timed out after '15s' between 19:43 and 19:48.
    • device_list showed the booted iPhone from old saved state, but device_open on that iPhone failed with "Device list failed: Could not communicate with device support". DeviceService.open always calls refresh (DeviceService.ts:716). It doesn't fall back to the known device the way DeviceService.ts:907 does, so a slow hub blocks opening a device that is already booted and known.

    Suggestions:

    • Raise the list timeout, or make it scale with load.
    • Have open use the known booted device when the refresh times out.
    • Report a timeout as "the device hub is slow to respond" rather than as a communication failure.

    Investigated with Claude Code (claude-opus-5-5) via T3 triage.

  2. ceolinwill commented on Nov 3, 2026

    @ceolinwill

    Note

    🤖 Claude Opus 5.5 responding on behalf of Will

    Another host-load case (Mac Studio, 16 cores, load average often 30–120, many agent threads sharing 3 simulators and 2–3 emulators). It adds two things to this thread: the same 15 s limit also makes Android shutdowns look failed when they worked, and device_open waits for it twice.

    Over 7 days on 0.1.5 and an earlier build, agents got "Could not communicate with device support" 37 times. Grouped by operation:

    • "Device list failed" (6: 5 from device_open, 1 from device_close). Each took 30–50 s. In device_open, DeviceService.list times out after 15 s and swallows the error, then open's own refresh times out again and fails.
    • device_close with shutdown: true on an Android emulator, "Device shutdown failed" (4). These took 15.7–32 s. Every time, the next device_list (5–15 s later) showed the emulator off, so the shutdown worked and only the 15 s wait in hubJson gave up. The iOS branch of DeviceHubOperations.shutdown already checks the device list before reporting a failure; the Android branch doesn't.
    • Boot and iOS attach (1 each). These failed after 3m12s and 3m07s (BOOT_TIMEOUT).
    • Screenshots (25). 18 of these failed in under 1.5 s, 17 of them on iPhone Duo simulators. Those were most likely hub errors (HTTP 500), which 0.1.5 also reported as "Could not communicate". Since fix(mcp): preserve actionable device screenshot errors #25216, 0.1.6 reports them as hub_rejected. Six others failed after 5–8 s and one hit the 20 s screenshot limit.
    • A stale "No device" error. When the refresh fails, device_open looks the id up in the old list and can answer "No device " instead of reporting the list failure. I filed that separately in 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.

    Since updating to 0.1.6 on Nov 2, I've seen none of these in 377 device tool calls, including today at load average 90–120. The 15 s limits on main are unchanged, though, so the same load could bring the failures back.

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