OutlineStyle crashes on Android but not on iOS
Current behaviour
In updating my project to Expo 53 (RN 0.79.5, RNP 5.14.5), I got crashes on Android, but not on iOS. With Expo dev tools it became clear that AndroidTextInput was receiving a ReadableNativeMap that it couldn't cast to a String (in Java). According to RNP:src:components:TextInput:TextInput.tsx:Props:outlineStyle, it's supposed to be a StyleProp<ViewStyle>, which works fine on iOS. But, on Android, it crashes. Since the type definitions don't allow for the newer (I think) outlineWidth property, I've worked around the problem thus:
const workaround = isAndroid ? { outlineWidth: 1 } : { outlineStyle: { borderWidth: 1 } }
return <TextInput {...workaround} />
and this seems to work fine.
I don't know where the discrepancy comes it, but maybe someone working on this project knows, FWIW.
Expected behaviour
No crash, and getting a border of width 1.
How to reproduce?
Build a project with a Paper TextInput and set outlineStyle to { borderWidth: 1} on Android.
Preview
https://photos.app.goo.gl/mxwqP1HV19R3tCif9
What have you tried so far?
I have a workaround; see above
Your Environment
| software | version |
|---|---|
| ios | x |
| android | 14 |
| react-native | 0.79.5 |
| react-native-paper | 5.14.5 |
| node | 22.14.0 |
| npm or yarn | yarn 4.9.2 |
| expo sdk | 53.0.19 |
I am using "react-native-paper": "^5.14.5" and on RN0.80.2 I am facing the same issue with the below error logs
Error while updating prop outlineStyle java.lang.ClassCastException: com.facebook.react.bridge.ReadableNativeMap 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:152) at com.facebook.react.uimanager.ViewManagerPropertyUpdater$GenericViewManagerDelegate.setProperty(ViewManagerPropertyUpdater.kt:185) at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:103) at com.facebook.react.uimanager.ViewManager.createViewInstance(ViewManager.java:221) at com.facebook.react.uimanager.ViewManager.createView(ViewManager.java:148) at com.facebook.react.fabric.mounting.SurfaceMountingManager.createViewUnsafe(SurfaceMountingManager.java:674) at com.facebook.react.fabric.mounting.SurfaceMountingManager.preallocateView(SurfaceMountingManager.java:1085) at com.facebook.react.fabric.mounting.mountitems.PreAllocateViewMountItem.execute(PreAllocateViewMountItem.kt:38) at com.facebook.react.fabric.mounting.MountItemDispatcher.executeOrEnqueue(MountItemDispatcher.java:347) at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchPreMountItemsImpl(MountItemDispatcher.java:325) at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchPreMountItems(MountItemDispatcher.java:300) at com.facebook.react.fabric.FabricUIManager$DispatchUIFrameCallback.doFrameGuarded(FabricUIManager.java:1486) at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.kt:25) at com.facebook.react.modules.core.ReactChoreographer.frameCallback$lambda$1(ReactChoreographer.kt:59) 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:1749) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1760) at android.view.Choreographer.doCallbacks(Choreographer.java:1216) at android.view.Choreographer.doFrame(Choreographer.java:1132) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1707) at android.os.Handler.handleCallback(Handler.java:959) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loopOnce(Looper.java:257) at android.os.Looper.loop(Looper.java:342) at android.app.ActivityThread.main(ActivityThread.java:9634) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) unknown:FabricUIManager com.fahr.stg E Exception thrown when executing UIFrameGuarded com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'outlineStyle' of a view managed by: AndroidTextInput at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter.updateViewProp(ViewManagersPropertyCache.java:101) at com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.setProperty(ViewManagerPropertyUpdater.kt:152) at com.facebook.react.uimanager.ViewManagerPropertyUpdater$GenericViewManagerDelegate.setProperty(ViewManagerPropertyUpdater.kt:185) at com.facebook.react.uimanager.ViewManager.updateProperties(ViewManager.java:103) at com.facebook.react.uimanager.ViewManager.createViewInstance(ViewManager.java:221) at com.facebook.react.uimanager.ViewManager.createView(ViewManager.java:148) at com.facebook.react.fabric.mounting.SurfaceMountingManager.createViewUnsafe(SurfaceMountingManager.java:674) at com.facebook.react.fabric.mounting.SurfaceMountingManager.preallocateView(SurfaceMountingManager.java:1085) at com.facebook.react.fabric.mounting.mountitems.PreAllocateViewMountItem.execute(PreAllocateViewMountItem.kt:38) at com.facebook.react.fabric.mounting.MountItemDispatcher.executeOrEnqueue(MountItemDispatcher.java:347) at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchPreMountItemsImpl(MountItemDispatcher.java:325) at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchPreMountItems(MountItemDispatcher.java:300) at com.facebook.react.fabric.FabricUIManager$DispatchUIFrameCallback.doFrameGuarded(FabricUIManager.java:1486) at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.kt:25) at com.facebook.react.modules.core.ReactChoreographer.frameCallback$lambda$1(ReactChoreographer.kt:59) 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:1749) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1760) at android.view.Choreographer.doCallbacks(Choreographer.java:1216) at android.view.Choreographer.doFrame(Choreographer.java:1132) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1707) at android.os.Handler.handleCallback(Handler.java:959) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loopOnce(Looper.java:257) at android.os.Looper.loop(Looper.java:342) at android.app.ActivityThread.main(ActivityThread.java:9634) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) Caused by: java.lang.ClassCastException: com.facebook.react.bridge.ReadableNativeMap 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)
This seems to be tied to the mode property. If you set the outlineStyle while mode='flat', it causes this crash on Android. Switching to mode='outlined' when setting the outlineStyle resolved the issue for me.
// Crash on Android but fine on iOS
<TextInput
mode='flat'
outlineStyle={{
borderWidth: 2,
borderRadius: 10
}}
/>
// Perfectly fine on both Android & iOS
<TextInput
mode='outlined'
outlineStyle={{
borderWidth: 2,
borderRadius: 10
}}
/>
This doesn't seem to affect iOS regardless of which mode is set.