A framework for building native applications using React
fix(android): crash on resetting borderStyle with props 2.0 (#56228)
Summary: ### The problem When enabling props 2.0 with the feature flags: ``` override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = true override fun enableExclusivePropsUpdateAndroid(): Boolean = true override fun enablePropsUpdateReconciliationAndroid(): Boolean = true ``` setting the style for `borderStyle` to undefined causes a crash: https://github.com/user-attachments/assets/f54fa3cb-44a2-4e35-a542-1013132fc076 <details> <summary>Expand for crash stack</summary> ``` Error while updating prop borderStyle java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String at com.facebook.react.uimanager.ViewManagersPropertyCache$StringPropSetter.getValueOrDefault(ViewManagersPropertyCache.java:291) at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:86) at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.kt:155) at com.facebook.react.uimanager.ViewManagerPropertyUpdater$GenericViewManagerDelegate.setProperty(ViewManagerPropertyUpdater.kt:188) at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:102) at com.facebook.react.fabric.mounting.SurfaceMountingManager.updateProps(SurfaceMountingManager.kt:635) at com.facebook.react.fabric.mounting.SurfaceMountingManager.updateProps(SurfaceMountingManager.kt:598) at com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem.execute(IntBufferBatchMountItem.kt:127) at com.facebook.react.fabric.mounting.MountItemDispatcher.executeOrEnqueue(MountItemDispatcher.kt:379) at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchMountItems$lambda$7$lambda$6(MountItemDispatcher.kt:269) at com.facebook.react.fabric.mounting.MountItemDispatcher.$r8$lambda$4xp_oXLXKRRjXh_WfqmwhGWbzaM(Unknown Source:0) at com.facebook.react.fabric.mounting.MountItemDispatcher$$ExternalSyntheticLambda4.invoke(D8$$SyntheticClass:0) at com.facebook.react.internal.tracing.PerformanceTracer.trace(PerformanceTracer.kt:46) at com.facebook.react.internal.tracing.PerformanceTracer.trace(PerformanceTracer.kt:35) at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchMountItems(MountItemDispatcher.kt:250) at com.facebook.react.fabric.mounting.MountItemDispatcher.tryDispatchMountItems(MountItemDispatcher.kt:94) at com.facebook.react.fabric.FabricUIManager$DispatchUIFrameCallback.doFrameGuarded(FabricUIManager.java:1581) at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.kt:42) at com.facebook.react.modules.core.ReactChoreographer.frameCallback$lambda$1(ReactChoreographer.kt:58) at com.facebook.react.modules.core.ReactChoreographer.$r8$lambda$nSkFhrr5T7rop_XKwzlLov4NLLw(Unknown Source:0) at com.facebook.react.modules.core.ReactChoreographer$$ExternalSyntheticLambda0.doFrame(D8$$SyntheticClass:0) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1628) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1639) at android.view.Choreographer.doCallbacks(Choreographer.java:1235) at android.view.Choreographer.doFrame(Choreographer.java:1160) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1613) at android.os.Handler.handleCallback(Handler.java:1070) at android.os.Handler.dispatchMessage(Handler.java:125) at android.os.Looper.dispatchMessage(Looper.java:333) at android.os.Looper.loopOnce(Looper.java:263) at android.os.Looper.loop(Looper.java:367) at android.app.ActivityThread.main(ActivityThread.java:9287) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) ``` </details> ### The bug & its fix The problem is that we clear the value of `borderStyle` using `NULL`: https://github.com/facebook/react-native/blob/4f908f433044279b7340c1933792b15aa5796a32/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp#L382 where `NULL` seems to be defined as `0`: <img width="545" height="315" alt="Screenshot 2026-03-26 at 09 12 56" src="https://github.com/user-attachments/assets/704ccd04-59f1-453f-8104-f56e57410b2d" /> so, folly treats this as a `0.0` and we get a double for a value meant to be `null` / optional. The fix is to change this to a proper folly nullish-value, as this PR does. This fixes the crash: https://github.com/user-attachments/assets/32ab68bc-536d-47be-88e1-74d141e7718b (I think there are other places where this is being misused, but i will make individual PRs for those cases!) ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [ANDROID] [FIXED] - Fixed crash when enabling props 2.0 and setting `borderStyle` to `undefined` Pull Request resolved: https://github.com/facebook/react-native/pull/56228 Test Plan: You can test the crash before with the following code in the playground app: https://github.com/facebook/react-native/compare/main...hannojg:react-native:hannojg/reproduction-borderstyle-issue?expand=1 You can then test and see how this fix resolves the crash. Reviewed By: javache Differential Revision: D98322741 Pulled By: zeyap fbshipit-source-id: d80c490b8570bb1a098d6234df91a9d5cade4df3
H
Hanno J. Gödecke committed
9e058db4c8f1d2aa7ab632606b565f43e6664adc
Parent: f10cded
Committed by meta-codesync[bot] <215208954+meta-codesync[bot]@users.noreply.github.com>
on 3/26/2026, 8:35:21 PM