Skip to content

Android build fails on React Native 0.85 due nullable Promise.reject signatures #83

Closed

Description

@wcastand

Summary

@expensify/react-native-wallet@0.1.21 fails to compile on Android with React Native 0.85 / Expo SDK 56 because the Kotlin Promise.reject(...) overrides in android/src/main/java/com/expensify/wallet/Utils.kt use non-null String for code, while React Native's Promise interface now expects nullable String?.

Changing the code parameter type to String? in each override fixes the compile failure.

Environment

  • @expensify/react-native-wallet: 0.1.21
  • react-native: 0.85.3
  • expo: ~56.0.0
  • Android build task: :expensify_react-native-wallet:compileDebugKotlin

Failure

> Task :expensify_react-native-wallet:compileDebugKotlin
e: .../node_modules/@expensify/react-native-wallet/android/src/main/java/com/expensify/wallet/Utils.kt:48:25 Class '<anonymous>' is not abstract and does not implement abstract members:
fun reject(code: String?, message: String?): Unit
fun reject(code: String?, throwable: Throwable?): Unit
fun reject(code: String?, message: String?, throwable: Throwable?): Unit
fun reject(code: String?, userInfo: WritableMap): Unit
fun reject(code: String?, throwable: Throwable?, userInfo: WritableMap): Unit
fun reject(code: String?, message: String?, userInfo: WritableMap): Unit
e: .../node_modules/@expensify/react-native-wallet/android/src/main/java/com/expensify/wallet/Utils.kt:59:13 'reject' overrides nothing. Potential signatures for overriding:
fun reject(code: String?, message: String?): Unit
fun reject(code: String?, throwable: Throwable?): Unit
fun reject(code: String?, message: String?, throwable: Throwable?): Unit
fun reject(code: String?, userInfo: WritableMap): Unit
fun reject(code: String?, throwable: Throwable?, userInfo: WritableMap): Unit
fun reject(code: String?, message: String?, userInfo: WritableMap): Unit

> Task :expensify_react-native-wallet:compileDebugKotlin FAILED

Patch

This patch fixed the build locally:

diff --git a/android/src/main/java/com/expensify/wallet/Utils.kt b/android/src/main/java/com/expensify/wallet/Utils.kt
index 9d0f1b0..c89b86f 100644
--- a/android/src/main/java/com/expensify/wallet/Utils.kt
+++ b/android/src/main/java/com/expensify/wallet/Utils.kt
@@ -56,44 +56,44 @@ object Utils {
               )
             }
 
-            override fun reject(code: String, userInfo: WritableMap) {
-              val errorMessage = "Error: $code\nUserInfo: $userInfo"
+            override fun reject(code: String?, userInfo: WritableMap) {
+              val errorMessage = "Error: ${code ?: "Unknown code"}\nUserInfo: $userInfo"
               continuation.resumeWithException(
                 Exception(errorMessage)
               )
             }
 
-            override fun reject(code: String, message: String?) {
-              val errorMessage = "Error: $code\nMessage: ${message ?: "No message provided"}"
+            override fun reject(code: String?, message: String?) {
+              val errorMessage = "Error: ${code ?: "Unknown code"}\nMessage: ${message ?: "No message provided"}"
               continuation.resumeWithException(
                 Exception(errorMessage)
               )
             }
 
-            override fun reject(code: String, message: String?, userInfo: WritableMap) {
+            override fun reject(code: String?, message: String?, userInfo: WritableMap) {
               val errorMessage =
-                "Error: $code\nMessage: ${message ?: "No message provided"}\nUserInfo: $userInfo"
+                "Error: ${code ?: "Unknown code"}\nMessage: ${message ?: "No message provided"}\nUserInfo: $userInfo"
               continuation.resumeWithException(
                 Exception(errorMessage)
               )
             }
 
-            override fun reject(code: String, message: String?, throwable: Throwable?) {
-              val errorMessage = "Error: $code\nMessage: ${message ?: "No message provided"}"
+            override fun reject(code: String?, message: String?, throwable: Throwable?) {
+              val errorMessage = "Error: ${code ?: "Unknown code"}\nMessage: ${message ?: "No message provided"}"
               continuation.resumeWithException(
                 throwable ?: Exception(errorMessage)
               )
             }
 
-            override fun reject(code: String, throwable: Throwable?) {
-              val errorMessage = "Error: $code"
+            override fun reject(code: String?, throwable: Throwable?) {
+              val errorMessage = "Error: ${code ?: "Unknown code"}"
               continuation.resumeWithException(
                 throwable ?: Exception(errorMessage)
               )
             }
 
-            override fun reject(code: String, throwable: Throwable?, userInfo: WritableMap) {
-              val errorMessage = "Error: $code\nUserInfo: $userInfo"
+            override fun reject(code: String?, throwable: Throwable?, userInfo: WritableMap) {
+              val errorMessage = "Error: ${code ?: "Unknown code"}\nUserInfo: $userInfo"
               continuation.resumeWithException(
                 throwable ?: Exception(errorMessage)
               )

Verification

After applying this patch in a consuming app using Bun patched dependencies:

  • bun android -- --no-bundler succeeds
  • the debug APK installs and opens on an Android emulator
  • TypeScript/lint checks in the consuming app still pass

Would you be open to accepting this compatibility fix for React Native 0.85+?

Pretty obvious but still, done with codex on Pi harness just in case so patch work in our repo but don't know about retro compatibility.

Activity

  1. JakubKorytko commented on Oct 8, 2026

    @JakubKorytko
    Member

    Verified this is fixed. On a fresh RN 0.85.3 app, :expensify_react-native-wallet:compileDebugKotlin fails on 0.1.21 with the exact error above and passes on the current main (0.1.38). 0.1.22 switched the overrides to nullable code, and since 0.1.37 (#94) getAsyncResult uses PromiseImpl instead of overriding reject, so this can't come back on any RN version. Closing, feel free to reopen if you still see it on 0.1.37+.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions