## TL;DR
Reproduce the crash with the release scheme locally, read the device crash log, and fix the usual causes: a Hermes bytecode or JavaScript bundle mismatch, a native module missing from the release configuration, or code that only runs in development. Install the exact TestFlight build, pull its crash report from the device or App Store Connect, and symbolicate against the release dSYM. Do not debug from the simulator debug build; it hides this class of failure.

```text
React Native release build crash on startup after TestFlight install: debug missing Hermes error
```

## Use this when
- The release build crashes instantly on launch from TestFlight while debug works.
- Hermes is enabled and the JavaScript bundle was built separately from the native binary.
- A new native dependency was added since the last store release.

## Not for this skill when
- The crash happens later in a specific user flow. That needs flow-level debugging, not startup triage.
- The app is rejected by review for the same crash. The crash log here is still the starting point, but respond through Resolution Center.

## Steps
1. Install the TestFlight build on a physical device, reproduce the crash, and fetch the crash log from the device analytics or App Store Connect crashes section. Verify: a crash report for the exact build is saved locally
2. Symbolicate the report with the dSYM from the same archive used for the upload. Verify: the stack trace shows readable function names in your code and React Native frames
3. Read the top frames and exception type and classify the crash: JavaScript bundle load, native module init, or Hermes bytecode mismatch. Verify: the crash class is named based on the trace, not guessed
4. Rebuild the archive ensuring the JavaScript bundle is generated by the release build phase, not copied from a debug build, and that the Hermes version matches the React Native version. Verify: the build log shows the bundle and Hermes compilation steps for the release configuration
5. Run the release scheme on a device with Metro disconnected to prove no development dependency remains. Verify: the app launches and reaches the home screen with no packager running
6. Upload the fixed build with a new build number and have an internal tester cold-launch it before external release. Verify: the tester confirms a clean launch on the new TestFlight build
7. Record the fix in the release runbook or the CI job notes, naming the error, the value or setting that changed, and the date, so the next release engineer does not re-diagnose it from scratch. Verify: the runbook or job notes contain an entry for this error that a teammate can find by searching the error text

## Why it happens
Release builds differ from debug in three ways that matter at startup: Hermes compiles the bundle ahead of time, the packager is absent, and native release configurations exclude development-only code. A mismatch in any of the three crashes before the first screen renders, and the absence of Metro means no red-box error ever appears. Only the archived builds own crash log describes the real failure.

In practice this failure is rarely a one-off. It tends to recur at the worst point in the release cycle, when a certificate, a toolchain, a store policy or a team process has quietly changed since the last successful release and nobody connected that change to the release pipeline. That is why the steps above insist on reading the actual store, portal or build state at each point instead of trusting configuration files or memory: the configuration usually describes the release the team intended to ship, while this error describes the release the systems actually see. Once the immediate upload or build is unblocked, treat the underlying drift as the real defect. Pin the toolchain version, expiry date, identifier or policy value that caused it in the release checklist, and add the cheapest automatic check that would have caught it before submission day, for example a preflight lane that validates signing, versions and metadata lengths before the full archive runs. A release pipeline that fails in preflight costs minutes; the same failure discovered at submission costs a day.

## Variants and edge cases
### React Native TestFlight crash on launch Hermes
Hermes-focused phrasing for the bytecode mismatch case. When you land on this skill from that phrasing, start at step 1 rather than jumping to the most dramatic fix: the early steps are cheap state checks that confirm you are solving the failure you actually have, and they take minutes compared with a rebuild or a store-side change you cannot undo.
### release build crashes debug works React Native
The classic phrasing; compare release configuration against debug. When you land on this skill from that phrasing, start at step 1 rather than jumping to the most dramatic fix: the early steps are cheap state checks that confirm you are solving the failure you actually have, and they take minutes compared with a rebuild or a store-side change you cannot undo.
### Edge case: Proguard-like stripping on iOS via dead code
Aggressive release settings can strip dynamically loaded modules. Check release-only linker settings if the trace points at a missing class. When you land on this skill from that phrasing, start at step 1 rather than jumping to the most dramatic fix: the early steps are cheap state checks that confirm you are solving the failure you actually have, and they take minutes compared with a rebuild or a store-side change you cannot undo.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_b3TyHhX4UXRO56ktDqKldA
