react / react/react-native

Fast Refresh disconnects repeatedly on iOS 26 simulator (iPhone 17 Pro), stable on iOS 18 / Android

Đang mở
#56,447 6 bình luận 5 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Needs: Attention Needs: Repro Platform: Android Platform: iOS
Ngôn ngữ chính
C++
Star
127k
Fork
25.3k
Merge trung bình
1 ngày 23 giờ
Pull request đã merge (30 ngày)
4

Mô tả

Description

On an iOS 26 simulator (iPhone 17 Pro, iOS 26.4 runtime), Fast Refresh / HMR disconnects from Metro within ~20–30 seconds of the app launching, with no visible JS error. The simulator shows the Fast Refresh disconnected. Reload app to reconnect. banner. Reloading briefly reconnects; the socket is dropped again shortly after. Interval to first drop varies from ~20 seconds to a few minutes but reproduces reliably.

The same Metro instance, started once, simultaneously serves an iPhone SE (2nd gen) / iOS 18 simulator and an Android emulator without any disconnections. Only the iOS 26 simulator drops, ruling out anything Mac-side (Metro, Watchman, port conflicts, firewall).

Reproduces on a stock npx @react-native-community/cli init project with zero custom code, native modules, or dev tooling — ruling out any userland cause.

Workaround (deterministic): hardcoding the bundle URL to http://127.0.0.1:8081/... in AppDelegate.bundleURL() (bypassing RCTBundleURLProvider) keeps Fast Refresh stable indefinitely. Reverting to the default provider reproduces the drop within 30 seconds. This strongly suggests the cause is hostname resolution / NSURLSession behavior specific to iOS 26 simulator runtimes.

Steps to reproduce
  1. On macOS with Xcode 26.x and the iOS 26.4 simulator runtime installed.
  2. Create a fresh project:
    npx @react-native-community/cli init rnbaseline --version 0.83.1
    cd rnbaseline
    
  3. Start Metro: yarn start
  4. Build and run on iPhone 17 Pro / iOS 26.4 simulator:
    yarn ios --simulator="iPhone 17 Pro"
    
  5. Let the app idle on the default screen.
  6. Within ~20–30 seconds the Fast Refresh disconnected banner appears.

Running the same app on an iPhone SE (2nd gen) / iOS 18 simulator or on an Android emulator in parallel shows no disconnection.

Mitigations tried (none resolved it except the workaround)
  • Updated iOS 26 simulator runtime from 26.1 → 26.4 (#56183 referenced 26.4 as fixing other 26.x bugs) — no effect
  • Removed all custom dev tooling (Reactotron, Storybook, etc.) — reproduces on stock RN init
  • yarn start --reset-cache — no effect
  • watchman watch-del-all && watchman shutdown-server — no effect
  • Verified no port 8081 conflicts with lsof -i :8081 — clean
  • Hardcoding http://127.0.0.1:8081/... in AppDelegate.bundleURL() → FIXES THE ISSUE (deterministic)
React Native Version

0.83.1

Affected Platforms

Runtime - iOS

Output of npx @react-native-community/cli info
System:
  OS: macOS 26.3.1
  CPU: (11) arm64 Apple M3 Pro
  Memory: 128.09 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.21.1
    path: /Users/uktam/.nvm/versions/node/v22.21.1/bin/node
  Yarn:
    version: 3.6.4
    path: /Users/uktam/.nvm/versions/node/v22.21.1/bin/yarn
  npm:
    version: 10.9.4
    path: /Users/uktam/.nvm/versions/node/v22.21.1/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.2
      - iOS 26.2
      - macOS 26.2
      - tvOS 26.2
      - visionOS 26.2
      - watchOS 26.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2025.2 AI-252.25557.131.2521.14344949
  Xcode:
    version: 26.3/17C529
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.17
    path: /opt/homebrew/Cellar/openjdk@17/17.0.17/libexec/openjdk.jdk/Contents/Home/bin/javac
  Ruby:
    version: 2.6.10
    path: /Users/uktam/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 20.0.0
    wanted: 20.0.0
  react:
    installed: 19.2.0
    wanted: 19.2.0
  react-native:
    installed: 0.83.1
    wanted: 0.83.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true
Stacktrace or Logs

No stacktrace — this is a silent WebSocket drop, not a crash.

React DevTools console (client-side)
Cannot connect to Metro.

Try the following to fix the issue:
- Ensure that Metro is running and available on the same network
- Ensure that the Metro URL is correctly set in AppDelegate

URL: localhost:8081

Error: undefined
Metro server output

yarn start --verbose produces no error or warning at the moment the banner appears. The disconnect is silent from the server's perspective.

iOS 26 simulator network logs (log stream)

Filter used:

log stream --predicate 'process == "rnbaseline" AND subsystem == "com.apple.network"' --info

Every connection to the dev server resolves to both IPv4 and IPv6 endpoints and then runs Happy Eyeballs:

nw_endpoint_resolver_update [C22.1 Hostname#...:8081 in_progress resolver ...] Adding endpoint handler for IPv4#...:8081
nw_endpoint_resolver_update [C22.1 Hostname#...:8081 in_progress resolver ...] Adding endpoint handler for IPv6#...:8081

The IPv6 candidate fails (Metro listens only on IPv4):

nw_socket_handle_socket_event [C6365.1.1:1] Socket received CONNRESET event
nw_socket_handle_socket_event [C6365.1.1:1] Socket SO_ERROR [61: Connection refused]
[C6365.1.1 IPv6#...:8081 failed socket-flow ...] event: flow:failed_connect @0.005s, error Connection refused

and falls back to IPv4. One loopback TCP handshake was observed taking Duration: 2.099s — well above the expected sub-10ms for loopback — suggesting Happy Eyeballs contention.

Suspected cause (not fully confirmed)

The dual-stack resolution pattern appears in both "unstable" and "stable (with hardcode)" runs, so IPv4/IPv6 racing alone doesn't fully explain the intermittency. What is consistently true is that bypassing hostname-based resolution by hardcoding 127.0.0.1 stops the disconnect deterministically. The exact mechanism — IPv6 race, resolver caching, or some other iOS 26-specific NSURLSession behavior — needs maintainer investigation.

Suggested mitigation in RN

Either of these should mask the underlying iOS 26 simulator regression:

  • Default RCTBundleURLProvider to 127.0.0.1 (not the host's resolvable name) when running in an iOS 26+ simulator, or
  • Have Metro bind to both IPv4 and IPv6 by default so dual-stack resolution doesn't fail half its candidates.
Adjacent issues (context, not duplicates)
  • #54845 — iPhone 17 Pro / iOS 26.1, different symptom (dev reload crash); closed as invalid.
  • #54859 — iOS 26 TurboModule startup crash.
  • #56183 — iOS 26 simulator CoreText bug, fixed in 26.4 runtime. Confirms Apple has shipped multiple broken simulator runtimes for iOS 26.
  • External: iOS 26.4-beta WKWebView reports document WebSocket-to-IP-address connections taking seconds to establish or failing, with 0.0.0.0 as workaround — suggests a shared NSURLSession regression.
MANDATORY Reproducer

Reproducible on clean 0.83.1 React Native CLI template

Screenshots and Videos

iCloud shared access

Dropover Cloud (valid for 3 months)

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với AppDelegate.bundleURL() và RCTBundleURLProvider, sau đó tái hiện việc ngắt kết nối bằng template React Native 0.83.1 sạch và các bước đã cung cấp cho trình mô phỏng iOS 26. So sánh URL hostname mặc định với workaround 127.0.0.1 được hardcode; được xem là hoàn tất khi Fast Refresh vẫn duy trì kết nối trên iOS 26, trong khi hành vi hiện có trên iOS 18 và Android vẫn ổn định.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
ios, react-native
Lĩnh vực
mobile-dev, networking
Loại issue
Lỗi
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Cần làm rõ
Mức phù hợp với người mới
32/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.