Conversation
) # Why When installing an app onto a physical iOS device, Apple's xcrun devicectl tool frequently drops the connection immediately after the initial handshake, throwing com.apple.dt.CoreDeviceError error 4000 (0xFA0). Because @expo/cli currently reads stderr synchronously on the process close event (childProcess.stderr.read()), this error is often swallowed if the stream is already flushed. This results in an unhelpful Error: null crash that leaves developers confused and without any actionable debugging information. Furthermore, the lack of a retry mechanism means these transient network/USB disconnects strictly fail the build every time. # How 1. Fixed `Error: null` masking: Replaced the synchronous stderr.read() call with an asynchronous stderr.on('data', ...) buffer accumulator to reliably capture and surface the true error output from the Apple toolchain. 2. Added Exponential Backoff: Wrapped the devicectl spawn logic in an exponential backoff retry loop (up to 3 attempts). 3. Targeted Retries: The retry loop strictly checks the error message and only intercepts transient disconnect errors (CoreDeviceError / 0xFA0). All other deterministic errors fail immediately. 4. Preserved Cancellation: Explicitly catches error.code === 'detached' to ensure that user cancellations (e.g., pressing Ctrl+C) immediately abort the process instead of trapping the developer in the retry loop. 5. Preserved UX: Maintained the asynchronous spawn approach and standard IO parsing so the CLI ora spinner and 34%... progress updates remain fully functional. # Test Plan - Ran npx expo run:ios --device <uuid> targeting a physical iPhone via USB. - Before: Observed an immediate CLI crash outputting Error: null. - After (Error surfacing): Verified that the CLI successfully captures and prints the underlying CoreDeviceError error 4000 (0xFA0). - After (Retry Logic): Verified that the CLI catches the transient error, waits 2 seconds, updates the ora spinner to Installing (attempt 2), and successfully installs the app on the second attempt without breaking the event loop. - Cancellation: Verified that pressing Ctrl+C during an installation attempt successfully and immediately aborts the process. # Checklist - [X] I added a `changelog.md` entry and rebuilt the package sources according to [this short guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting) - [X] This diff will work correctly for `npx expo prebuild` & EAS Build (eg: updated a module plugin). - [ ] Conforms with the [Documentation Writing Style Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md) --------- Co-authored-by: Phil Pluckthun <phil@kitten.sh>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )