Hive Hive
Sign in

tuist run <preview>: “Fetching the list of devices failed” — devicectl transportType: "sameMachine" (simulators) fails to decode

GitHub issue · Open

Metadata
Source
tuist/tuist #12052
Updated
Jul 23, 2026
Domains
CLI
Details

What happened?

tuist run <preview-url> (and the macOS menu-bar app) always fail with “Fetching the list of devices failed.” It fails before any device can be selected — even for simulator targets — so previews can’t be launched at all.

Root cause: DeviceController.findAvailableDevices() runs xcrun devicectl list devices --json-output <path> and decodes it with a single strict JSONDecoder().decode(DeviceList.self, …), mapping any decode error to DeviceControllerError.fetchingDevicesFailed.

On current Xcode/CoreDevice, devicectl list devices includes simulators, and every simulator entry has "transportType": "sameMachine". But DeviceList.Result.Device.ConnectionProperties.TransportType only defines localNetwork and wired. "sameMachine" is a present-but-unknown enum value, so decoding TransportType? throws (Swift doesn’t decode an unknown raw value as nil), and because the whole list is decoded in one shot the entire fetch fails.

This is not covered by #8001/#8010 — that fix handles devices with missing properties (made name/udid/platform optional + compactMap). The compactMap runs after decode, so it can’t help an enum that throws during decode.

How do we reproduce it?

# 1. Confirm devicectl returns simulators with the offending value:
xcrun devicectl list devices --json-output - | python3 -m json.tool | grep transportType
# -> "transportType": "sameMachine" (for every "reality": "simulated" entry)
# 2. Run any preview:
tuist run <any-preview-url>
# -> "Fetching the list of devices failed."

Minimal offending device entry (sanitized) from devicectl:

{
"connectionProperties": { "transportType": "sameMachine", "tunnelState": "disconnected" },
"deviceProperties": { "name": "iPad (10th generation)", "osVersionNumber": "18.2" },
"hardwareProperties": { "platform": "iOS", "reality": "simulated", "udid": "…" }
}

Environment: Tuist 4.202.6 · Tuist macOS app 0.25.3 · macOS 26.5.2 (25F84) · Xcode 26.6 (17F113) · devicectl 642.4

Error log

Error
Fetching the list of devices failed.
Sorry this didn't work. Here's what to try next:
If the error is actionable, address it
If the error is not actionable, let's discuss it in the Troubleshooting & how to
▸ If you are very certain it's a bug, file an issue
Check out the logs at ~/.local/state/tuist/sessions/<id>/logs.txt

The session log shows the preview GET returning 200, immediately followed by the Noora “Fetching the list of devices failed.” alert. The underlying DecodingError (unknown TransportType value "sameMachine") is swallowed by the catch in DeviceController.findAvailableDevices().

macOS version

26.5.2 (25F84)

Tuist version

4.202.6

Xcode version

26.6 (17F113)

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments
D
dosubot[bot] Jul 23, 2026

Hi @lore-lml! I’m Dosu and I’m helping the Tuist team.

Great analysis — I can confirm this is a valid bug. The TransportType enum in DeviceController.swift only defines localNetwork and wired, so when devicectl returns "sameMachine" for simulators, JSONDecoder throws a DecodingError before the compactMap filter can run, taking down the entire device list.

The fix would involve two changes in DeviceController.swift:

  1. Add the missing case to the TransportType enum [1]:

    enum TransportType: String, Codable {
    case localNetwork
    case wired
    case sameMachine
    }
  2. Handle it in the mapping to PhysicalDevice [2]:

    let transportType: PhysicalDevice.TransportType? = switch device.connectionProperties.transportType {
    case .localNetwork: .wifi
    case .wired: .usb
    case .sameMachine: .none // simulators — no physical transport
    case .none: .none
    }

A more resilient alternative would be to implement a custom init(from decoder:) on TransportType that decodes unknown raw values as nil instead of throwing, which would future-proof against any other new transport types Apple may add. Something like:

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode(String.self)
self = TransportType(rawValue: rawValue) ?? .unknown
}

This would prevent future breakage if Apple introduces additional transport types.

To reply, just mention @dosu.


Docs are dead. Just use Dosu.

Leave Feedback Ask Dosu about tuist Share Dosu with your team