Description
getMaxDisplayRefreshRate() in DdSdkImplementation.kt crashes with java.util.NoSuchElementException on Samsung Galaxy Fold 2 (Android 11) when display.supportedModes returns an empty array.
The issue is at line 400 in packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt:
return display.supportedModes.maxOf { it.refreshRate.toDouble() }
Iterable.maxOf() throws NoSuchElementException when the collection is empty. On Galaxy Fold devices — which have a foldable display with dynamic display mode switching — supportedModes can return an empty array during fold state transitions.
Reproduction
- Device: Samsung Galaxy Fold 2 (SM-F916N), Android 11
- SDK version:
@datadog/mobile-react-native 3.0.1 (also present in 3.0.2)
- React Native: 0.82 (New Architecture enabled)
- Frequency: Consistent on app launch / display configuration change
Crashlytics stack trace
Fatal Exception: java.util.NoSuchElementException
Sequence is empty.
com.datadog.reactnative.DdSdkImplementation.getMaxDisplayRefreshRate (DdSdkImplementation.kt:400)
com.datadog.reactnative.DdSdkImplementation.initializeVitalMonitors (DdSdkImplementation.kt:377)
com.datadog.reactnative.DdSdkImplementation.initialize$lambda$2$lambda$1 (DdSdkImplementation.kt:109)
Expected Behavior
The SDK should gracefully handle an empty supportedModes array and fall back to DEFAULT_REFRESH_HZ (60.0) instead of crashing.
Suggested Fix
Replace maxOf with maxOfOrNull and provide the default fallback:
// Before (crashes on empty array)
return display.supportedModes.maxOf { it.refreshRate.toDouble() }
// After (safe)
return display.supportedModes.maxOfOrNull { it.refreshRate.toDouble() } ?: DEFAULT_REFRESH_HZ
This is a one-line change with zero behavioral impact when supportedModes is non-empty.
Workaround
We are using patch-package to apply this fix locally:
--- a/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt
+++ b/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt
@@ -397,7 +397,7 @@
val dm = context?.getSystemService(Context.DISPLAY_SERVICE) as? DisplayManager ?: return 60.0
val display: Display = dm.getDisplay(Display.DEFAULT_DISPLAY) ?: return DEFAULT_REFRESH_HZ
- return display.supportedModes.maxOf { it.refreshRate.toDouble() }
+ return display.supportedModes.maxOfOrNull { it.refreshRate.toDouble() } ?: DEFAULT_REFRESH_HZ
}
Affected Devices
Confirmed on foldable devices where display modes change dynamically:
- Samsung Galaxy Fold 2 (SM-F916N) — Android 11
- Likely affects all Galaxy Z Fold / Flip series
Environment
| Key |
Value |
@datadog/mobile-react-native |
3.0.1, 3.0.2 |
| React Native |
0.82 |
| Android |
11 (API 30) |
| Architecture |
New Architecture (Hermes) |
Description
getMaxDisplayRefreshRate()inDdSdkImplementation.ktcrashes withjava.util.NoSuchElementExceptionon Samsung Galaxy Fold 2 (Android 11) whendisplay.supportedModesreturns an empty array.The issue is at line 400 in
packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt:return display.supportedModes.maxOf { it.refreshRate.toDouble() }Iterable.maxOf()throwsNoSuchElementExceptionwhen the collection is empty. On Galaxy Fold devices — which have a foldable display with dynamic display mode switching —supportedModescan return an empty array during fold state transitions.Reproduction
@datadog/mobile-react-native3.0.1 (also present in 3.0.2)Crashlytics stack trace
Expected Behavior
The SDK should gracefully handle an empty
supportedModesarray and fall back toDEFAULT_REFRESH_HZ(60.0) instead of crashing.Suggested Fix
Replace
maxOfwithmaxOfOrNulland provide the default fallback:This is a one-line change with zero behavioral impact when
supportedModesis non-empty.Workaround
We are using
patch-packageto apply this fix locally:Affected Devices
Confirmed on foldable devices where display modes change dynamically:
Environment
@datadog/mobile-react-native