By default, the New Relic React Native agent captures JavaScript errors and unhandled promise rejections and reports them as MobileJSError events. You can view these errors in the UI, query them with NRQL, and chart them in dashboards.
To make the stack traces in MobileJSError events human-readable, the agent needs the source map that corresponds to the JavaScript bundle running in your app. When you configure your New Relic User API key and application token correctly, the agent uploads the source map for you automatically after each build. If you can't upload automatically, or you ship JavaScript-only updates with CodePush or another over-the-air (OTA) service, you can upload source maps manually.
Important
Source map upload uses a User API key in addition to the application token. The application token identifies your app, but it doesn't authenticate a specific user, so it can't safely authorize an upload on its own. The User API key ties the request to an authenticated New Relic user, which prevents anyone who only has the (less sensitive) application token from uploading or overwriting your source maps. The User API key and the application token must belong to the same New Relic account.
Conseil
JavaScript error reporting is enabled by default. Set the jsErrorReportingEnabled configuration setting to false to disable recording of MobileJSError events entirely.
Set up automatic source map upload
To upload source maps automatically, provide your New Relic User API key and application token. Because a React Native app builds separately for each platform, you configure the key differently on Android and iOS. Set it up for each platform you ship.
Before you begin, get the following from the same New Relic account:
- A User API key.
- Your mobile application token (the same token you pass to
NewRelic.startAgent()).
Android
Add your User API key to the newrelic.properties file in your project:
com.newrelic.api_key=<YOUR_USER_API_KEY>Replace <YOUR_USER_API_KEY> with your User API key. The agent already knows the application token from NewRelic.startAgent(). When both values are valid, the agent generates and uploads the Android source map to New Relic automatically after each release build.
Conseil
Automatic upload only runs for release builds by default. To get automatic source map upload for debug builds too, add Debug to the uploadMapsForVariant setting in your New Relic Gradle plugin configuration, for example uploadMapsForVariant("Release", "Debug"). Otherwise, upload the debug build's source map manually.
iOS
On iOS, a build-phase script (upload-react-native-sourcemap) included in the dsym-upload-tools folder — the same folder used for dSYM uploads — uploads the source map. You pass the User API key and application token as arguments to that script.
If you haven't already set up dSYM uploads, copy the
dsym-upload-toolsfolder into your project'sSRCROOT(typically youriosfolder).In Xcode, select your target, open the Build Phases tab, and add a New Run Script Build Phase. Drag it to run after the "Bundle React Native code and images" phase.
Add the following to the run script, replacing the placeholders with your User API key and application token:
bash$ARTIFACT_DIR="${BUILD_DIR%Build/*}"$SCRIPT=`/usr/bin/find "${SRCROOT}" "${ARTIFACT_DIR}" -type f -name upload-react-native-sourcemap | head -n 1`$/bin/sh "${SCRIPT}" "YOUR_USER_API_KEY" "YOUR_APP_TOKEN"
Conseil
Don't commit credentials to version control. Store the User API key and application token in an .xcconfig file or your CI/CD system's secrets, then reference them in the run script (for example, "${NR_USER_API_KEY}" "${NR_APP_TOKEN}"). Add --debug as a third argument to write verbose output to upload_sourcemap_results.log.
The iOS script runs only for Release builds and skips simulator builds. If either value is missing or invalid, the agent won't upload the source map, and JavaScript error stack traces will remain unsymbolicated. In that case, upload the source map manually.
Manually upload a source map
You can upload a source map directly to the New Relic symbol ingest API. This is useful when automatic upload isn't possible, or when you release JavaScript-only updates through CodePush or other OTA services.
Use the following cURL template:
$curl -X POST "https://symbol-ingest-api.service.newrelic.com/v1/react-native/sourcemaps" \> -H "Api-Key: $NR_USER_API_KEY" \> -H "X-APP-LICENSE-KEY: $NR_APP_TOKEN" \> -F "sourcemap=@./index.android.bundle.map" \> -F "jsBundleId=<JS_BUNDLE_ID>" \> -F "appVersion=1.0.5" \> -F "sourcemapName=index.android.bundle.map"Replace the following:
$NR_USER_API_KEYis a valid New Relic User API key.$NR_APP_TOKENis your mobile monitoring application token.<JS_BUNDLE_ID>is the unique build identifier reported by the agent for the JavaScript session (see Retrieve the jsBundleId).appVersionis the native application version the bundle targets (for example,1.0.5).
Conseil
For accounts on New Relic's EU data center, use the EU endpoint instead: https://symbol-ingest-api.service.eu.newrelic.com/v1/react-native/sourcemaps.
For accounts on New Relic's Japan data center, use the Japan endpoint instead: https://symbol-ingest-api.service.jp.newrelic.com/v1/react-native/sourcemaps.
Upload API reference
Endpoint
Property | Value |
|---|---|
Method |
|
URL |
|
Content-Type |
|
Headers
Header | Required | Description |
|---|---|---|
| Yes | A valid New Relic User API key. It must belong to the same account as the application token. |
| Yes | The application token for the mobile app. |
| No | Telemetry information about the bundler, source map names, and sizes. When a source map exceeds 200 MB unzipped, the agent doesn't send the file and instead transmits this header only. |
| Yes | Must be |
Request body (multipart form data)
Field | Type | Required | Description |
|---|---|---|---|
| File | No | The source map file ( |
| String | No | Name of the source map file. Maximum 255 characters. |
| String | Yes | Unique build identifier (for example, a SHA or ID). Maximum 255 characters. |
| String | Yes | Application version (for example, |
Important
If the source map file exceeds 200 MB unzipped, the agent won't send the file. Instead, it transmits the X-Telemetry-Data header so New Relic can still track that a build occurred. For details, see File size limitations.
Responses
Responses use Content-Type: application/json.
HTTP status | Description |
|---|---|
| The upload succeeded. The response body contains the source map metadata: |
| Validation failed, for example missing fields, an invalid JSON schema in the file, or a malformed request. Example: |
| The API key is valid, but the |
| The |
| The application token provided in the header doesn't exist. Example: |
| The unzipped source map file exceeds 200 MB. Example: |
| A generic, unrecoverable error occurred on the server side. Example: |
Upload source maps for CodePush and OTA updates
When you use CodePush or another OTA update service, the JavaScript bundle version diverges from the native binary version. Each time you push a JavaScript update, upload the new source map so that MobileJSError events remain readable in New Relic.
To symbolicate an OTA update, the upload must use:
- A unique
jsBundleIdthat matches the ID the agent reports during the JavaScript session. - The correct
appVersion, which is the native version the bundle targets.
You can upload the source map with a script in your CI/CD pipeline or manually with cURL.
Method 1: Automated upload via script
New Relic provides a Node.js helper script that you can run in your CI/CD pipeline immediately after the appcenter codepush release-react command.
$# Example integration$appcenter codepush release-react -a <Owner>/<App>$node upload-nr-sourcemap.js --bundle android/index.android.bundle --map android/index.android.bundle.map --bundleId <NEW_ID>Method 2: Manual upload via cURL
If you prefer not to use the script, upload the source map (unzipped or zipped) to the symbol ingest API with cURL:
$curl -X POST "https://symbol-ingest-api.service.newrelic.com/v1/react-native/sourcemaps" \> -H "Api-Key: $NR_USER_API_KEY" \> -H "X-APP-LICENSE-KEY: $NR_APP_TOKEN" \> -F "sourcemap=@./index.android.bundle.map" \> -F "jsBundleId=CODE_PUSH_ID_HERE" \> -F "appVersion=1.0.5" \> -F "sourcemapName=index.android.bundle.map"For the full list of headers, body fields, and responses, see the upload API reference.
Retrieve the jsBundleId
The jsBundleId used for the upload must match the bundle ID the agent reports for the JavaScript session. For CodePush releases, use the CodePush deployment or release identifier as the jsBundleId so the uploaded source map maps to the bundle running in your users' apps.
Conseil
To verify, audit, or remove source maps you've uploaded, see List and delete React Native source maps.
File size limitations
Source map files must be under 200 MB unzipped to be stored for symbolication.
Our build scripts automatically gzip the .map file before upload to reduce transfer size, but the build checks the 200 MB limit against the unzipped file. If the unzipped .map file exceeds 200 MB, the agent doesn't upload the file, which prevents build timeouts and ingestion errors.
In these cases, the script sends build telemetry (metadata) instead of the file. This lets New Relic track that a build occurred, even though symbolication isn't available for that specific version. As a result, MobileJSError events for that build show unsymbolicated (minified) stack traces.
If your source map is larger than 200 MB unzipped, reach out to New Relic Support or file a feature request. There's no way to raise this limit yourself.
Troubleshoot source map uploads
If your MobileJSError stack traces aren't symbolicated, your source map may have exceeded the 200 MB unzipped size limit. Use the following steps to confirm the cause and request help. For more troubleshooting tips and frequently asked questions, see Troubleshoot React Native source maps and JavaScript errors.
Confirm whether the file or telemetry was uploaded
A successful build doesn't always mean a successful file upload. If your build script completes with a Success message but your source map is larger than 200 MB unzipped, check your console logs. You'll see a message indicating that the agent sent telemetry instead of the source map file.
Check the unzipped file size
Check the size of your source map file to verify whether you're near or over the limit:
$# Check the size of the unzipped source map$ls -lh index.android.bundle.mapIf the file is near or above 200 MB, the source map can't be uploaded for symbolication.
Request support for large source maps
If your unzipped source map exceeds the 200 MB limit, there's no way to reduce it on your side or raise the limit yourself. Do the following to let us know this limit affects you:
- Contact New Relic Support.
- File a feature request to raise your source map size limit.