Troubleshooting and SDK errors (React Native)
This page covers errors from both of our React Native SDKs. The first sections describe the Components SDK (@weavr-io/secure-components-react-native), which wraps the native iOS and Android components SDKs and returns a uniform Result shape. The final section covers the Push ProvisioningPush Provisioning A method that allows cardholders to add their card to a digital wallet (such as Apple Pay or Google Pay) directly from your app. The card details are securely tokenized and sent to the wallet provider, streamlining the process and enhancing the user experience compared to manual provisioning. This feature is currently in beta. SDK (@weavr-io/push-provisioning-react-native).
For the complete list of underlying native error codes, refer to the iOS and Android error references.
Before you start: Expo Modules runtime
Our SDK is built as an Expo Module, which means it requires the Expo Modules runtime. This applies equally to bare React Native projects and managed Expo workflows. If the runtime is missing or incompletely wired up, you'll see one of these build errors before any of the runtime errors that follow appear:
- iOS:
No such module 'ExpoModulesCore' - Android:
project :expo-modules-core not found
If you encounter either, revisit the Install Expo Modules step on the get-started page. You don't need to migrate your app to Expo - Expo officially supports installing the Expo Modules runtime into an existing bare React Native app.
Xcode 26 iOS build failure
Symptom: iOS builds fail on Xcode 26 with errors deep inside the fmt Pod - the C++ formatting library that React Native pulls in transitively. Errors reference consteval or FMT_USE_CONSTEVAL and don't point at any of your own code.
Cause: Xcode 26's Clang advertises support for consteval via __cpp_consteval, so fmt flips FMT_USE_CONSTEVAL to 1 and takes a code path that the new compiler can't actually compile. This isn't specific to our SDK - it affects any React Native or Expo iOS build on Xcode 26 until fmt ships an upstream fix. Tracking: expo/expo#44229.
Fix: patch fmt/include/fmt/base.h from your Podfile so FMT_USE_CONSTEVAL is forced back to 0. Patching from post_install keeps the workaround in place across pod install re-runs without you editing Pod sources by hand. Add (or extend) the post_install block in ios/Podfile:
post_install do |installer|
# Xcode 26 workaround: patch fmt to disable consteval.
fmt_base = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h')
if File.exist?(fmt_base)
content = File.read(fmt_base)
unless content.include?('Xcode 26 workaround')
patched = content.gsub(
/^(#elif defined\(__cpp_consteval\)\n# define FMT_USE_CONSTEVAL) 1/,
"// Xcode 26 workaround: disable consteval\n\\1 0"
)
if patched != content
File.chmod(0644, fmt_base)
File.write(fmt_base, patched)
end
end
end
end
Then re-run pod install from ios/ and rebuild. consteval is a compile-time optimization; flipping it to 0 makes fmt fall back to constexpr with no runtime impact.
This is a workaround - once fmt releases an upstream fix and Expo or React Native picks it up, drop the patch and update the Pod. If you can't apply the patch, downgrading to Xcode 15 also resolves it. For a longer walk-through of the same fix, see "Xcode 26.4 Just Broke Your React Native Build".
Error shape
Async methods return a Result<T, WeavrError> rather than rejecting. The WeavrError carries a string code, a message, and an optional localized message:
export interface WeavrError {
code: string;
message: string;
localizedMessage?: string;
}
The Result type discriminates on error:
const { value, error } = await initializeUXComponents(env, WEAVR_UI_KEY);
if (error) {
console.log(error.code, error.message);
return;
}
// Success - `value` is the typed result.
The known top-level codes are exposed as the ErrorCodes enum:
| Code | Description |
|---|---|
Unknown | An unclassified error. Inspect message for the underlying reason. |
MissingData | The native module returned no data and no error. Usually indicates a transport-layer bug. |
LoginAlreadyInProgress | A biometric login is already running. Wait for it to complete before starting another. |
For HTTP-driven failures, code carries the server status code (for example, "401", "403", "5xx"). For SDK-level failures, code carries the underlying native WeavrErrorCode (for example, "1001" for cantSetUIKey). See the iOS and Android pages for the full integer reference.
Initialize components
initializeUXComponents resolves to Result<UXComponentsStatus, WeavrError>. Common failures map to these underlying native codes:
| Code | Description |
|---|---|
1001 | The UI keyUI key A public key that authorizes Weavr's Secure UI components - the inputs and displays in our Web, Android, iOS, and React Native SDKs that handle passwords, PINs, card details, and KYC/KYB flows. Unlike the API key, the UI key isn't an API credential; you don't call REST endpoints with it. It's safe to embed in client-side code, and Sandbox and Live each have their own UI key. is missing or could not be set. |
1002 | The secure field length could not be fetched or is not available. |
1003 | The device key pair could not be created or restored. |
1004 | The biometric security service could not be initialized. |
1005 | The server public key could not be retrieved. |
initializePSA runs synchronously and assumes initializeUXComponents succeeded first. If the underlying native call throws, the exception propagates to your caller - wrap it in a try/catch if you need to handle it.
Set user token
setUserToken resolves to Result<string, WeavrError>. The error's code is one of:
- An HTTP status code from the token validation or association API call.
- An SDK-level code (typically
"1001") for local precondition failures such as a missing UI keyUI key A public key that authorizes Weavr's Secure UI components - the inputs and displays in our Web, Android, iOS, and React Native SDKs that handle passwords, PINs, card details, and KYC/KYB flows. Unlike the API key, the UI key isn't an API credential; you don't call REST endpoints with it. It's safe to embed in client-side code, and Sandbox and Live each have their own UI key..
Common HTTP status codes
| Code | Description |
|---|---|
| 400 | Bad request. |
| 401 | Unauthorized. |
| 403 | Forbidden. |
| 404 | Not found. |
| 409 | Conflict. |
| 412 | Precondition failed. |
| 429 | Too many requests. |
| 5xx | Server error (500, 502, 503, 504, and others). |
Update FCM token
updateFCMToken resolves to Result<boolean, WeavrError>. Failures use the same code conventions as setUserToken: an HTTP status code from the device-token API call, or "1001" if the UI keyUI key A public key that authorizes Weavr's Secure UI components - the inputs and displays in our Web, Android, iOS, and React Native SDKs that handle passwords, PINs, card details, and KYC/KYB flows. Unlike the API key, the UI key isn't an API credential; you don't call REST endpoints with it. It's safe to embed in client-side code, and Sandbox and Live each have their own UI key. is missing.
Tokenize secure fields
createTokens resolves to Result<CreateTokenResponse, WeavrError>. Failures use:
| Code | Description |
|---|---|
1001 | The UI keyUI key A public key that authorizes Weavr's Secure UI components - the inputs and displays in our Web, Android, iOS, and React Native SDKs that handle passwords, PINs, card details, and KYC/KYB flows. Unlike the API key, the UI key isn't an API credential; you don't call REST endpoints with it. It's safe to embed in client-side code, and Sandbox and Live each have their own UI key. is missing. |
1002 | The passcode length has not been fetched, or the input length doesn't match the requirement. |
-1 | A runtime exception occurred during tokenizationTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants.. |
| HTTP | Server error during the tokenizationTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants. API call. |
Start biometric enrollment
startEnrollment resolves to a BiometricsEnrollmentResult discriminated union - not a Result. Branch on the case field:
| Case | Description |
|---|---|
completed | The enrollment flow completed successfully. |
initialisationError | The SDK was not properly initialized when enrollment was triggered. The error field describes what went wrong. |
cryptographyError | An error occurred in the cryptography module. The error field describes the cause. |
failedBiometricsChallenge | The user failed the biometrics challenge. |
unauthorized | The token is not authorized. Sign the user in again and provide a new token. |
userDoesNotConsent | The user dismissed the consent screen without confirming. |
failedToLoadBrand | The flow could not launch because the biometrics configuration couldn't be fetched. |
noPhoneNumberAvailable | The user has no associated phone number. |
noBiometricsAvailable | Biometrics are not available. The biometricAvailability field is noHardware, hwUnavailable, or noneEnrolled. |
challengeFailed | The enrollment challenge failed (for example, the OTP expired). The cause field carries the reason. |
const result = await startEnrollment();
switch (result.case) {
case "completed":
// Enrolled.
break;
case "noBiometricsAvailable":
if (result.biometricAvailability === "noneEnrolled") {
// Prompt the user to enroll a fingerprint or face in system settings.
}
break;
case "challengeFailed":
console.log(result.cause);
break;
// ...
}
Start biometric login
startBiometricLogin resolves to Result<WeavrSecureLoginData, WeavrError>. The error's code is one of:
- An HTTP status code from the login, verification, or password-fallback API call.
- An SDK-level code for local precondition failures.
SDK-level error codes
| Code | Description |
|---|---|
1001 | The UI keyUI key A public key that authorizes Weavr's Secure UI components - the inputs and displays in our Web, Android, iOS, and React Native SDKs that handle passwords, PINs, card details, and KYC/KYB flows. Unlike the API key, the UI key isn't an API credential; you don't call REST endpoints with it. It's safe to embed in client-side code, and Sandbox and Live each have their own UI key. is missing. |
1003 | No enrollment key is on the device. Call startEnrollment first. |
1005 | The server public key required for password fallback could not be retrieved. |
2001 | The Play Integrity token, challenge ID, nonce, or initial login response is invalid. |
-1 | Local biometric authentication failed, the prompt was canceled, or another local error occurred. |
Troubleshooting Invalid Origin (HTTP 403)
On Android, all HTTP 403 responses are mapped to Invalid Origin. The first call to surface this is usually login, but the underlying cause is shared across the SDK. See Troubleshooting ENROLLMENT_FAILED: Invalid Origin on the Android page for the full root-cause matrix (Play Integrity setup, GCP project linking, environment-key mismatch, sideloaded builds).
Start biometric SCA challenge
startChallenge resolves to Result<WeavrChallengeResult, WeavrError>. The error's code is one of:
| Code | Description |
|---|---|
1001 | The UI keyUI key A public key that authorizes Weavr's Secure UI components - the inputs and displays in our Web, Android, iOS, and React Native SDKs that handle passwords, PINs, card details, and KYC/KYB flows. Unlike the API key, the UI key isn't an API credential; you don't call REST endpoints with it. It's safe to embed in client-side code, and Sandbox and Live each have their own UI key. is missing. |
1003 | The enrollment key is missing. |
2001 | The challenge ID or nonce is missing. |
-1 | The server returned an empty response, or a local exception occurred. |
| HTTP | Server error during challenge retrieval or verification. |
Decline operations follow the same code conventions as verify.
Start KYC flow
KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. errors are reported through the KYCErrorType enum. Listen via the KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. SDK callbacks on the component:
| Type | Description |
|---|---|
Unknown | An unexpected error occurred. |
InvalidParameters | Invalid parameters were provided to the KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. flow. |
Unauthorized | The user is not authorized; the token is invalid or expired. |
InitialLoadingFailed | Initial loading of the KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. flow failed. |
ApplicantNotFound | The KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. applicant could not be found. |
ApplicantMisconfigured | The KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. applicant is misconfigured in our system. |
NetworkError | A network error occurred during the KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. process. |
UnexpectedError | An unexpected error occurred that doesn't fit other categories. |
InititlizationError | KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. initialization failed. |
Push provisioning SDK
Our push-provisioning SDK (@weavr-io/push-provisioning-react-native) wraps the native iOS (Apple Wallet) and Android (Google Wallet) provisioning SDKs. This section documents the unified error shape, the cross-platform error codes, and where to look for platform-specific detail.
Push provisioning error shape
AddToWalletButton reports the outcome through its onComplete prop. On failure, error is a WeavrError; on success, error is null and value carries the result:
export type ErrorCode = "Failed" | "Canceled" | "Unknown";
export interface WeavrError<T = ErrorCode> {
code: T;
message: string;
weavrErrorCode?: string;
}
| Field | Description |
|---|---|
code | A high-level classifier: Failed (the SDK couldn't complete the flow), Canceled (the user backed out), or Unknown. |
message | A human-readable description of the failure. |
weavrErrorCode | The underlying native error code (for example, CARD_NOT_ELIGIBLE). Use this to branch on specific scenarios. |
<AddToWalletButton
// …
onComplete={({ error, value }) => {
if (error) {
switch (error.weavrErrorCode) {
case "CARD_NOT_ELIGIBLE":
// Surface to the user; escalate to the issuer if needed.
break;
case "NETWORK_ERROR":
// Retry with backoff.
break;
default:
console.error(error.code, error.message);
}
return;
}
// Success.
}}
/>
getCardStatusInWallet and isGooglePayAvailable reject with the same WeavrError shape - handle them via .catch() or try/await.
Push provisioning error codes
The following codes can appear in error.weavrErrorCode. Some codes are platform-specific because Apple Wallet and Google Wallet expose different failure modes:
| Code | Platform | Scenario | Recommended action |
|---|---|---|---|
SDK_NOT_INITIALISED | Both | Initialization missing | Initialize the SDK before any provisioning call. |
CARD_NOT_PROVISIONED | Both | Set-default attempted on an unknown card | Prompt the user to add the card first. |
NETWORK_ERROR | Both | Connectivity issue | Retry with backoff; surface an offline state. |
CARD_NOT_ELIGIBLE | Both | The backend flagged the card as ineligible | Show a user-friendly message; escalate to the issuer. |
COULD_NOT_FETCH_PROVIDER | Both | Missing routing data from the backend | Validate the backend response and provisioning configuration. |
UNAUTHORIZED | Both | Token missing or rejected | Refresh the authentication token. |
MISSING_* (2001–2007) | Both | AddToWalletButton missing parameters | Ensure all required props are set before the user taps. |
SETUP_ERROR | Both | Local app misconfiguration | Revisit the installation steps; check manifest metadata (Android) or bundle configuration (iOS). |
UNKNOWN_ERROR | Both | Unmapped exception | Capture logs and contact our support team. |
GOOGLE_PAY_PROVISIONING_PAYLOAD_ERROR | Android | Google Pay SDK payload error | Validate the card data and retry. |
INSECURE_DEVICE_ERROR | Android | Device not secure (debugging or rooted) | Inform the user; provisioning is blocked on insecure devices. |
CLIENT_NOT_AVAILABLE_ERROR | Android | Google Pay client unavailable | Prompt the user to update Google Play Services. |
GOOGLE_PAY_ERROR | Android | Google Pay SDK general error | Check device compatibility and Google Play Services. |
GOOGLE_PAY_TOKEN_ALREADY_EXISTS | Android | The card is already provisioned | Update the UI to reflect the provisioned state. |
GOOGLE_PAY_TOKEN_NOT_FOUND | Android | Token not found in Google Pay | Retry the card-status check or prompt re-provisioning. |
INVALID_ACTIVITY | Android | Host is a non-FragmentActivity | Use AppCompatActivity, or attach the fragment correctly. |
The 3000-series Google Pay codes are Android-only. Apple Wallet has its own error surface - see the iOS push-provisioning errors section for the underlying iOS-specific codes (for example, cantBeAddedToAppleWallet, cantObtainPaymentPassRequestConfiguration).
See also
- iOS components SDK errors - the underlying native error reference for iOS.
- Android components SDK errors - the underlying native error reference for Android, including the
Invalid Origintroubleshooting matrix.