The fix
The simulator you named does not exist on that machine. Pick from what is actually installed instead of guessing a name:
xcrun simctl list devices available # see real names and runtimes
xcodebuild test -scheme App \
-destination 'platform=iOS Simulator,name=iPhone 16' # a name from the list
# or, most robust in CI: resolve a UDID first
UDID=$(xcrun simctl list devices available -j | python3 -c 'import sys,json;print(next(d["udid"] for r,ds in json.load(sys.stdin)["devices"].items() if "iOS" in r for d in ds if d["name"].startswith("iPhone")))')
xcodebuild test -scheme App -destination "platform=iOS Simulator,id=$UDID"
Why it happens on GitHub Actions
GitHub's macos-* images ship a set of simulators that changes between image versions — and sometimes between runs of the same image. In a benchmark we ran, one in six macos-15 jobs failed with this error for iPhone 16 Pro while the other five had it. Hard-coding a device name is a flake waiting to happen; resolving a UDID at job start is not.
If you also pass OS=17.5-style versions, the runtime must be installed too; OS=latest is safer.
Avoiding the problem
On mac.doublespeed.ai the fleet's simulators are fixed and listed at GET /v1/xcode/capabilities; a job that names a missing device fails at submission with a clear INVALID_REQUEST instead of after a 3-minute VM boot. From a Linux runner:
- uses: doublespeed-main/xcode-action@v1
with:
api-key: ${{ secrets.DS_API_KEY }}
destination: platform=iOS Simulator,name=iPhone 16 Pro
Runs took about 40 s push-to-green versus 4–5 minutes on macos-15 in the same benchmark (details).
Agents without a Mac build, test and run iOS apps through mac.doublespeed.ai (npm i -g @doublespeed/ds).