-
Notifications
You must be signed in to change notification settings - Fork 25.1k
Description
Description
I've noticed the following bug / crash.
imagine you have a codegen spec with a Float that you want to be optional:
type NativeProps = Readonly<{
...ViewProps,
testFloatNullable?: CodegenTypes.Float,actually codegen doesn't make this type in the native specs nullable, but instead will set a default value of 0f. To make it truly nullable we have to use WithDefault:
type NativeProps = Readonly<{
...ViewProps,
testFloatNullable?: WithDefault<CodegenTypes.Float, null>,In kotlin, this will generate the following ViewManagerInterface:
public interface RNTMyNativeViewManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
void setTestFloatNullable(T view, @Nullable Float value);
}This looks correct, nice!
Now to the problem: If in the ViewManager implementation I do @ReactProp(name = "testFloatNullable") an error is thrown making the app crash (see stacktrace).
When using @ReactProp it will be added by the FallbackViewManagerSetter we create here:
Line 107 in 8af50b2
| setter = FallbackViewManagerSetter(managerClass) |
(It seems like this is always generated for a view manager as the PropsSetter thing is not rolled out yet to OSS?)
In there it tries to create a setter for the java.lang.Float type, but there is no mapping for it, so it crashes later down in that function:
Line 440 in 8af50b2
| } else if (propTypeClass == float.class) { |
Now, this really started to get me wondering about the @ReactProp annotation.
Because the code will work fine, even when removing the annotation! That's because codegen'ed view managers update the props through their delegates:
Line 102 in 8af50b2
| delegate.setProperty(viewToUpdate, entry.getKey(), entry.getValue()); |
Only when the delegate is not specified would we make use of the fallback:
Lines 119 to 128 in 8af50b2
| protected ViewManagerDelegate<T> getDelegate() { | |
| if (this instanceof ViewManagerWithGeneratedInterface) { | |
| ReactSoftExceptionLogger.logSoftException( | |
| TAG, | |
| new ReactNoCrashSoftException( | |
| "ViewManager using codegen must override getDelegate method (name: " | |
| + getName() | |
| + ").")); | |
| } | |
| return new ViewManagerPropertyUpdater.GenericViewManagerDelegate<>(this); |
So, in my mind, if my view managers are all build for new arch and I properly use the delegate, I would not need to specify the @ReactProp.
Default values I would specify in my codegen spec using WithDefault.
If that's truly the case I feel like we should update the documentation on that?
Steps to reproduce
- In RNtester change the
MyNativeViewNativeComponentlike here: hannojg@10f13f9#diff-b5952b76e1edb5586bcd012664958340f987b8ec2c69c1b35d477b16a600c145 - On the native side implement the prop, add the @ReactProp annotation as shown here: hannojg@10f13f9#diff-edc21748fd95d8c2539af21c8d5bdb732bc7f1ed9d46e901604a32ec59862751
Compile & run the app, see the crash happening
React Native Version
0.83.1
Affected Platforms
Runtime - Android
Areas
Other (please specify)
Output of npx @react-native-community/cli info
info Fetching system and libraries information...
System:
OS: macOS 15.7.3
CPU: (14) arm64 Apple M4 Pro
Memory: 161.67 MB / 48.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.14.0
path: /nix/store/04fc23dsflkxl4s9p6lkigia1hq3vjp2-nodejs-22.14.0/bin/node
Yarn:
version: 1.22.22
path: /nix/store/04fc23dsflkxl4s9p6lkigia1hq3vjp2-nodejs-22.14.0/bin/yarn
npm:
version: 10.9.2
path: /nix/store/04fc23dsflkxl4s9p6lkigia1hq3vjp2-nodejs-22.14.0/bin/npm
Watchman:
version: 2024.03.11.00
path: /Users/hannogodecke/Documents/discord/.local/bin/watchman
Managers:
CocoaPods:
version: 1.16.2
path: /Users/hannogodecke/.rbenv/shims/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:
API Levels:
- "31"
- "34"
- "35"
- "36"
Build Tools:
- 34.0.0
- 35.0.0
- 35.0.1
- 36.0.0
System Images:
- android-35 | Google APIs ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
- android-35 | Pre-Release 16 KB Page Size Google Play ARM 64 v8a
- android-35 | Pre-Release 16 KB Page Size Google APIs ARM 64 v8a
- android-35 | Google APIs ATD ARM 64
- android-36 | Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2025.2 AI-252.25557.131.2521.14432022
Xcode:
version: 26.2/17C52
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.15
path: /Users/hannogodecke/.jenv/shims/javac
Ruby:
version: 3.4.4
path: /Users/hannogodecke/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 19.2.3
wanted: 19.2.3
react-native: Not Found
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: Not found
newArchEnabled: Not found
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Stacktrace or Logs
Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 7014 (mqt_v_js), pid 6950 (ook.react.uiapp)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'vivo/V2419_EEA/V2419:15/AP3A.240905.015.A2/compiler250531150613:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2026-01-29 16:25:33.449252220+0100
Process uptime: 5s
Cmdline: com.facebook.react.uiapp
pid: 6950, tid: 7014, name: mqt_v_js >>> com.facebook.react.uiapp <<<
uid: 10281
tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: 'JNI DETECTED ERROR IN APPLICATION: JNI GetObjectRefType called with pending exception java.lang.RuntimeException: Unrecognized type: class java.lang.Float for method: com.facebook.react.uiapp.component.MyNativeViewManager#setTestFloatNullable
at com.facebook.react.uimanager.ViewManagersPropertyCache$PropSetter com.facebook.react.uimanager.ViewManagersPropertyCache.createPropSetter(com.facebook.react.uimanager.annotations.ReactProp, java.lang.reflect.Method, java.lang.Class) (ViewManagersPropertyCache.java:464)
at void com.facebook.react.uimanager.ViewManagersPropertyCache.extractPropSettersFromViewManagerClassDefinition(java.lang.Class, java.util.Map) (ViewManagersPropertyCache.java:533)
at java.util.Map com.facebook.react.uimanager.ViewManagersPropertyCache.getNativePropSettersForViewManagerClass(java.lang.Class) (ViewManagersPropertyCache.java:392)
at void com.facebook.react.uimanager.ViewManagerPropertyUpdater$FallbackViewManagerSetter.<init>(java.lang.Class) (ViewManagerPropertyUpdater.kt:151)
at com.facebook.react.uimanager.ViewManagerPropertyUpdater$ViewManagerSetter com.facebook.react.uimanager.ViewManagerPropertyUpdater.findManagerSetter(java.lang.Class) (ViewManagerPropertyUpdater.kt:107)
at java.util.Map com.facebook.react.uimanager.ViewManagerPropertyUpdater.getNativeProps(java.lang.Class, java.lang.Class) (ViewManagerPropertyUpdater.kt:93)
at java.util.Map com.facebook.react.uimanager.ViewManager.getNativeProps() (ViewManager.java:414)
at java.util.Map com.facebook.react.uimanager.UIManagerModuleConstantsHelper.internal_createConstantsForViewManager(com.facebook.react.uimanager.ViewManager, java.util.Map, java.util.Map, java.util.Map, java.util.Map) (UIManagerModuleConstantsHelper.kt:185)
at com.facebook.react.bridge.NativeMap com.facebook.react.runtime.ReactInstance$Companion.getConstantsForViewManager(com.facebook.react.uimanager.ViewManager, java.util.Map) (ReactInstance.kt:626)
at com.facebook.react.bridge.NativeMap com.facebook.react.runtime.ReactInstance$Companion.access$getConstantsForViewManager(com.facebook.react.runtime.ReactInstance$Companion, com.facebook.react.uimanager.ViewManager, java.util.Map) (ReactInstance.kt:586)
at com.facebook.react.bridge.NativeMap com.facebook.react.runtime.ReactInstance._init_$lambda$1(com.facebook.react.runtime.ReactInstance, java.util.Map, java.lang.String) (ReactInstance.kt:230)
at com.facebook.react.bridge.NativeMap com.facebook.react.runtime.ReactInstance.$r8$lambda$OWzGsGT35XIobeFyjEj9NOErJWs(com.facebook.react.runtime.ReactInstance, java.util.Map, java.lang.String) (ReactInstance.kt:-1)
at com.facebook.react.bridge.NativeMap com.facebook.react.runtime.ReactInstance$$ExternalSyntheticLambda2.getConstantsForViewManager(java.lang.String) (D8$$SyntheticClass:0)
at void com.facebook.jni.NativeRunnable.run() (NativeRunnable.java:-2)
at void android.os.Handler.handleCallback(android.os.Message) (Handler.java:1014)
at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102)
at void com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(android.os.Message) (MessageQueueThreadHandler.kt:21)
at boolean android.os.Looper.loopOnce(android.os.Looper, long, int) (Looper.java:250)
at void android.os.Looper.loop() (Looper.java:340)
at void com.facebook.react.bridge.queue.MessageQueueThreadImpl$Companion.startNewBackgroundThread$lambda$0(com.facebook.react.common.futures.SimpleSettableFuture) (MessageQueueThreadImpl.kt:152)
at void com.facebook.react.bridge.queue.MessageQueueThreadImpl$Companion.$r8$lambda$YYXYCFexeoKtAeDpeNYkxZZlpbA(com.facebook.react.common.futures.SimpleSettableFuture) (MessageQueueThreadImpl.kt:-1)
at void com.facebook.react.bridge.queue.MessageQueueThreadImpl$Companion$$ExternalSyntheticLambda0.run() (D8$$SyntheticClass:0)
at void java.lang.Thread.run() (Thread.java:1012)
in call to GetObjectRefType
from void com.facebook.jni.NativeRunnable.run()'
MANDATORY Reproducer
Screenshots and Videos
No response