## TL;DR
Align the runtime version of the published update with the runtime version baked into the installed native build. Expo Updates serves an update only to builds whose runtime matches, so an update published under a new runtime, or after a version bump changed the fingerprint, silently never arrives. Check the runtime in the build and in the update, republish under the matching runtime or ship a new native build when the native side really changed.

```text
Expo OTA update not working on release channel: runtime version mismatch
```

## Use this when
- An eas update publishes successfully but release-channel devices never receive it.
- The app version or a native dependency changed since the store build.
- You use runtime version policies such as fingerprint or sdkVersion in app configuration.

## Not for this skill when
- The update channel itself is misconfigured. If even a same-runtime update fails, check channel and branch mapping first.
- Devices are offline or the app never checks for updates. Verify the update check code path separately.

## Steps
1. Read the runtime version embedded in the installed store build from the EAS build details or the apps update debug view. Verify: the store builds runtime value is recorded exactly
2. Read the runtime version attached to the published update in the EAS dashboard or update metadata. Verify: the updates runtime value is recorded for comparison
3. If they differ, decide which is authoritative: republish the JavaScript update under the store builds runtime when only JS changed. Verify: a republished update carries the store builds runtime
4. If native code or configuration changed, accept that OTA cannot deliver it and plan a new store build instead of republishing. Verify: the change is routed to a full build and store release
5. Check the channel points at the branch you published to in the EAS dashboard. Verify: channel and branch mapping matches the publish command used
6. Verify on a device with the store build: force an update check and confirm the new bundle downloads and applies on restart. Verify: the device reports the new update group after relaunch
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
Runtime version is Expos safety boundary between JavaScript updates and native binaries. Any native-relevant change, a new module, a config plugin change, sometimes even a version bump under some policies, produces a new runtime. The update service then correctly refuses to deliver mismatched updates, but it refuses silently from the users point of view.

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
### Expo updates runtime version mismatch release channel
The named mismatch phrasing; compare build and update runtimes. 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.
### eas update not showing on devices fix
Symptom phrasing; runtime first, then channel mapping. 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: fingerprint policy surprises
Under the fingerprint policy, harmless-looking config edits change the runtime. Pin runtimes manually for hotfix branches when you need OTA reach. 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_jXggWsaed-3xU3NVWr9tww
