Skip to content

fix(mobile): react-native-svg 15.15.1 and Lottie recycling for the new architecture - #14652

Merged
dylanjeffers merged 2 commits into
fix/mobile-rntp-bridgelessfrom
fix/mobile-new-arch-prereqs
Oct 9, 2026
Merged

dylanjeffers merged 2 commits into
fix/mobile-rntp-bridgelessfrom
fix/mobile-new-arch-prereqs

Conversation

@dylanjeffers

@dylanjeffers dylanjeffers commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Two native fixes the new-architecture flip (#14648) needs. They ship in 1.5.188 on the old arch, so 1.5.189 is only the flag flip.

Base: fix/mobile-rntp-bridgeless (#14647). Rebased 2026-10-08 onto the rebased #14647. Merge this into #14647, not main. The lockfiles were checked after the rebase: npm install and pod install (old arch) leave them unchanged, and scripts/patch-package.sh applies the Lottie workspace patch with --error-on-fail. On old arch neither one changes behavior. The svg change is behind RCT_NEW_ARCH_ENABLED, and the Lottie method only exists on the Fabric component view.

1. react-native-svg 15.15.0 → 15.15.1 (CPU regression, #14648 blocker 6)

On Fabric, 15.15.0 (software-mansion/react-native-svg#2802) has every SVG element push its bounds into a state update from drawRect (updateShadowNodeMetrics). Each update is a ShadowTree::commit. Reanimated 3's commit hook clones the tree and re-applies animated props on every commit, which redraws the SVGs, so the loop never settles. On an artist profile with nothing playing this held the app at ~150% CPU.

Evidence: an lldb breakpoint on EventDispatcher::dispatchStateUpdate on the profile showed every state update coming from -[RNSVGRenderable updateShadowNodeMetrics] / -[RNSVGGroup updateShadowNodeMetrics], called from -[RNSVGSvgView drawRect:]. Upstream reverted it in 15.15.1 (software-mansion/react-native-svg#2832, reported in #2831).

Result on the same profile (new arch, iOS 26.5 simulator, Release): 151.5% → 20.2%. Old arch on the same route is 16.3%.

package-lock.json changes only the nested packages/mobile/node_modules/react-native-svg entry, which stays nested because metro.config.js resolves it there. Podfile.lock changes only the RNSVG version and checksum.

2. Lottie: opt out of Fabric view recycling (#14648 blocker 5)

lottie-react-native 7.3.4 keeps autoPlay/loop and the loaded animation on the native container when Fabric recycles the view, while _props goes back to defaults. After the first play, the play bar's buffering spinner unmounts, its recycled view keeps playing, and its onAnimationFinish reaches AnimatedButton, which dispatches pause. The fix is +shouldBeRecycled { return NO; } via patch-package.

lottie-react-native is nested under packages/mobile/node_modules, which the root patch-package run can't reach. So the patch lives in packages/mobile/workspace-patches/, and scripts/patch-package.sh applies it from the mobile workspace.

Verified on the simulator: previous session, 3 cold launches with no self-pause, and again today on the full spike build (the first play kept playing).

🤖 Generated with Claude Code

@changeset-bot

changeset-bot Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: fedf1e1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@socket-security

socket-security Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Dependency limit exceeded — report not shown.

This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report.

Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard.

Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account.

dylanjeffers and others added 2 commits October 8, 2026 17:30
lottie-react-native 7.3.4 keeps autoPlay, loop and the loaded animation
on the native container when Fabric recycles the view, while _props goes
back to defaults. The play bar's buffering spinner unmounts after the
first play, its recycled view keeps playing, and its onAnimationFinish
reaches AnimatedButton, which dispatches pause.

Opt the component view out of recycling. lottie-react-native is nested
under packages/mobile/node_modules, so the patch is applied from that
workspace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
15.15.0 (#2802) makes every SVG element push its bounds into a Fabric
state update from drawRect (updateShadowNodeMetrics). Each update is a
ShadowTree commit, and with Reanimated's commit hook each commit clones
the tree and re-applies animated props, which redraws the SVGs and loops.
On a static profile this kept the JS thread at ~150% CPU on the new
architecture. 15.15.1 reverts it (software-mansion/react-native-svg#2832,

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dylanjeffers
dylanjeffers force-pushed the fix/mobile-rntp-bridgeless branch from f7df09b to 9e9ecef Compare October 9, 2026 00:33
@dylanjeffers
dylanjeffers force-pushed the fix/mobile-new-arch-prereqs branch from 87b0af7 to fedf1e1 Compare October 9, 2026 00:33
@dylanjeffers
dylanjeffers marked this pull request as ready for review October 9, 2026 22:29
@dylanjeffers
dylanjeffers merged commit e9db547 into fix/mobile-rntp-bridgeless Oct 9, 2026
23 of 24 checks passed
@dylanjeffers
dylanjeffers deleted the fix/mobile-new-arch-prereqs branch October 9, 2026 22:29
dylanjeffers added a commit that referenced this pull request Oct 9, 2026
…14647)

Prepares react-native-track-player 4.1.2 (Apache-2.0) for the new
architecture. It ships with 1.5.188 on the old architecture, where it
changes nothing.

**Base: `chore/mobile-rn-0.81` (#14642).** Rebased 2026-10-08 after
#14642 moved onto the 1.5.188 release branch (#14654). Merge #14652 into
this branch first, then this into #14642. Don't merge to main on its
own.

We are staying on RNTP 4.1.2. v5 (`@rntp/player`) is commercially
licensed. 4.1.2 is the last 4.x release, and the fixes below were never
published for it.

## Changes (Android only, in
`patches/react-native-track-player+4.1.2.patch`)

**1. Event emission in bridgeless mode**
(doublesymmetry/react-native-track-player#2593, #2619)
- `MusicService.emit()` / `emitList()` read the context from
`reactNativeHost.reactInstanceManager.currentReactContext`. That is null
in bridgeless mode, so every native-to-JS event was dropped: playback
state, active track, remote/notification controls, progress and errors.
- They now use the `reactContext` getter that `HeadlessJsTaskService`
already provides. It returns `ReactInstanceManager.currentReactContext`
on the old architecture (the same call as before) and
`ReactHost.currentReactContext` in bridgeless mode.
- That getter throws if `ReactHost` is null. Emission, `startTask` in
`onStartCommand`, and `super.onDestroy()` now log and carry on instead
of crashing the service. This is the same approach as upstream's fix for
#2619 (ed52dc5, v5 line).

**2. `@ReactMethod`s return `Unit`**
- Every `TrackPlayerModule` method was written as `fun play(callback:
Promise) = scope.launch { ... }`, so each one returned a `Job`.
- The bridgeless TurboModule interop layer rejects a non-void return on
an async method, so it threw while loading the module:
> Unable to parse @ReactMethod annotations from native module:
TrackPlayerModule

On the new architecture the app aborted at startup (found in the spike,
#14648).
- They are now `fun play(callback: Promise) { scope.launch { ... } }`.
The old bridge ignored the return value, so nothing changes there. The
diff touches only the first and last line of each of the 37 methods.

**Not applicable to 4.1.2:**
- #2670 (`BackgroundServiceStartNotAllowedException` while emitting in
the background) and #2662 (Android Auto cold start never starting the
headless task) are v5 issues. In v5, emitting an event starts a
`TrackPlayerTaskService`. In 4.1.2, `emit` never starts a service, and
`onStartCommand` already calls `startTask`, which creates the React host
when there is none. That cold path was checked on the new architecture
in the spike.
- iOS needs no change. The Swift `RCTEventEmitter` module works through
the interop layer as it is.

## Verification (old architecture, `prodRelease` arm64 signed with the
debug keystore, Android 16 emulator)
I tested with a temporary JS harness that was not committed. It wraps
the root component, logs every RNTP event with `console.warn` (visible
in logcat) and in an on-screen overlay, queues 3 public tracks, seeks,
and then seeks near the end. Signed out, `pm clear` before each launch,
and logcat confirmed `Loading JS bundle from
"assets://index.android.bundle"`.

| Check | Result |
|---|---|
| Release build | ✅ |
| Runtime arch | ✅ `bridgeless:false, fabric:false`, "Legacy
Architecture" warning |
| `PlaybackState` / `PlaybackActiveTrackChanged` reach JS | ✅ stopped →
loading → buffering → ready → playing, `index:0` |
| Seek | ✅ `seekTo(60)` → position 60–62.8 |
| Auto-advance | ✅ `active-track-changed` 0 → 1 at the end of track 0,
`getActiveTrackIndex()` = 1 |
| `adb shell cmd media_session dispatch pause/play/next` | ✅
`remote-pause` / `remote-play` / `remote-next` reach JS, and the state
follows |
| Notification shade pause / play / previous | ✅ `remote-pause`,
`remote-play`, `remote-previous` reach JS |
| Screen off and backgrounded for 75 s | ✅ progress events kept
arriving, MediaSession `PLAYING` |
| iOS Release (old arch, 26.5 sim) | ✅ unchanged: events, seek and
auto-advance all work |

The same harness on the new architecture is in the spike PR.

## Still needs a real device
Lock-screen and notification controls, Bluetooth, and background
playback for more than 2 minutes, together with the rest of the 1.5.188
checklist in #14642.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
dylanjeffers added a commit that referenced this pull request Oct 9, 2026
Phase 1 of the React Native upgrade: 0.79.5 → 0.81.6 with the old
architecture still on.

**Base: `chore/mobile-native-release-1.5.188` (#14654).** Rebased onto
it after 1.5.187 (#14645, which squashed #14627, #14640 and #14650)
merged to main; the two lib-swap commits are gone from this branch.
Merge #14647 and #14651 into this branch first, then this into #14654,
then #14654 into main as one push (see #14654 for the full order).

## Rebase onto 1.5.187 (2026-10-08)
- `patches/react-native+0.79.5.patch` (the ExceptionsManager Hermes fix
from #14643) is renamed to `react-native+0.81.6.patch`. The anchors are
unchanged in 0.81.6, and `scripts/patch-package.sh` applies it with
`--error-on-fail` during `npm install` (checked: `getErrorStackSafe` is
in the installed `ExceptionsManager.js`).
- notifee and Firebase from #14640 are kept as they are:
`@notifee/react-native` 9.1.8 is the latest release and
`@react-native-firebase/app`/`messaging` 24.1.1 build on 0.81.6 on the
old arch (both declare `react-native: *`). No bump needed.
- The Firebase Android BoM stays pinned to 33.16.0. This branch moves
Kotlin to 2.1.20, and BoM 34 needs 2.2, so the pin still applies; the
comment now says so.
- The UIScene and notifee lines in `AppDelegate.mm` (#14626, #14640) are
untouched by this branch.
- `package-lock.json` and `Podfile.lock` were regenerated (`npm
install`, then `RCT_NEW_ARCH_ENABLED=0 bundle exec pod install`); the
release xcconfig has no `RCT_NEW_ARCH_ENABLED=1`. The SwiftAudioEx
post_install patch (#14650) still applies.

**Needs a native release (1.5.188).** Don't OTA this JS onto older
binaries. Old architecture stays on: Android `newArchEnabled=false`, iOS
`RCTNewArchEnabled=false`, pods installed with `RCT_NEW_ARCH_ENABLED=0`.

Two commits, one per step. Each step builds on iOS and Android:
1. 0.79.5 → 0.80.3
2. 0.80.3 → 0.81.6 (0.81.6 is the latest 0.81 patch on npm)

## Version bumps

| Package | From | To | Why |
|---|---|---|---|
| react-native | 0.79.5 | 0.81.6 | the upgrade |
| `@react-native/*` (babel-preset, eslint-config, metro-config,
metro-babel-transformer, typescript-config) | 0.79.5 | 0.81.6 | must
match RN |
| `@react-native-community/cli`, `cli-platform-android`,
`cli-platform-ios` | 18.0.0 | 20.1.3 | CLI line for 0.81; the platform
packages were left at 18 on the old ladder branch |
| react, react-dom, react-test-renderer (whole monorepo, root
`overrides` too) | 19.0.0 | **19.1.4** | RN's bundled renderer throws at
startup unless `react` is **exactly** its version: 19.1.0 for 0.80.3,
19.1.4 for 0.81.6. The old ladder branch used 19.1.8, which would throw
"Incompatible React versions" on launch. |
| @types/react / @types/react-dom | 19.0.0 | 19.1.17 / 19.1.11 | match
React 19.1 |
| react-native-gesture-handler | 2.25.0 | 2.28.0 | 2.28 is the first 2.x
with official 0.81 support (2.25's table stops at 0.79). Stays on 2.x;
v3 drops the old architecture. |
| @amplitude/analytics-react-native | 1.4.11 | 1.4.14 | Kotlin 2.1 (RN
0.80+) turns the deprecated `toUpperCase(Locale)` in 1.4.11 into a
compile error |
| tiktok-opensdk-react-native | ^0.10.7 | 0.10.7 (pinned) | it now
carries a patch. 0.10.9 fixes the Android signature, but drops the
`handleOpenURL`/`handleUserActivity` declarations that SceneDelegate
imports |

Patches added (`patches/`):
- `react-native-track-player+4.1.2.patch`: Kotlin 2.1 rejects
`Arguments.fromBundle(Bundle?)`. Now resolves `null` when there is no
item. 4.1.2 is the last 4.x and has no fixed release.
- `tiktok-opensdk-react-native+0.10.7.patch`: `onNewIntent(intent:
Intent)` (RN 0.80 made `ActivityEventListener` non-null) and
`reactApplicationContext.currentActivity`.

Checked against 0.81 on the old architecture and left alone: Reanimated
3.19.5 (the official table lists 3.19.x for 0.78–0.81 on Paper;
Reanimated 4 is out of scope), track-player 4.1.2 (patched above),
collapsible-tab-view 8.0.1 (JS only), screens 4.18.0 (0.81 support since
4.14; `react-native-screens+4.18.0.patch` still applies; 4.25+ drops the
old arch), pager-view 6.7.1 (7+ drops the old arch), video 6.18.0, svg
15.15.0 (0.81 support since 15.12.1), google-cast 4.6.2 (5.x is new-arch
only), notifications 5.1.0, code-push 12.3.2 (README lists 0.77–0.86;
13.x needs a new OTA history), bootsplash 6.3.11, safe-area-context
5.6.2, keyboard-controller 1.19.0, flash-list 1.8.3, datetimepicker
8.3.0 (builds against 0.81.6).

## Template changes (rn-diff-purge 0.79.5 → 0.81.6)
- Android: Kotlin 2.0.21 → 2.1.20, Gradle 8.13 → 8.14.3, new
`gradlew`/`gradlew.bat`/wrapper jar, `MainApplication` uses
`loadReactNative(this)` in place of `SoLoader.init` plus `load()`, and
`edgeToEdgeEnabled=false` is added as in the template. The app already
draws edge-to-edge through react-native-bars and the SDK 36 target, so
this flag changes nothing.
- AGP comes from RN: 8.8 → 8.11.0, which supports compileSdk 36, so
`android.suppressUnsupportedCompileSdk=36` is removed.
- `settings.gradle` resolves `@react-native/gradle-plugin` through
`require.resolve` from `react-native`, not a hard-coded hoisted path.
With this lockfile npm nests it under
`node_modules/react-native/node_modules`.
- Kept: `newArchEnabled=false`, the `AudiusScrypt` module
(`ScryptPackage` is still registered), the debug manifest (it adds
`SYSTEM_ALERT_WINDOW`), and
`android:enableOnBackInvokedCallback="false"`.
- **Back handling:** since 0.80, `ReactActivity` registers an
`OnBackPressedCallback` when targetSdk ≥ 36, which calls
`onBackPressed()` → JS `BackHandler`. Our `invokeDefaultOnBackPressed`
override (`moveTaskToBack`) still runs. The manifest opt-out is kept as
asked and can probably go in a later release.
- iOS: no template change between 0.79.5 and 0.81.6. `Info.plist` and
`RichPushExtension/Info.plist` now set `RCTNewArchEnabled=false`, which
RN 0.80+ reads **at runtime**; a missing key means new arch. `pod
install` writes the key and re-sorts the plist each time, so the sorted
version is committed.

## AppDelegate / UIScene
No code change needed. `RCTAppDelegate` is marked deprecated in 0.81 in
favour of `RCTReactNativeFactory`, so there is a
`-Wdeprecated-declarations` warning, but every API we use is unchanged:
`automaticallyLoadReactNativeWindow`, `rootViewFactory`,
`createRootViewController`, `setRootView:toRootViewController:`,
`customizeRootView:`, `bundleURL`, and `dependencyProvider`.
`didFinishLaunching` still creates the factory and skips the window.
Moving to `RCTReactNativeFactory` can wait for the 0.82+ phase.

Verified on a Release build: cold launch, a deep link while killed, and
a deep link while backgrounded, on iOS 26.5 and iOS 27. iOS 27 needs
UIScene and showed no launch crash.

## Web / React 19.1
- Typecheck: web, common and harmony are clean, and so is mobile.
- `vite build` (prod env): succeeds.
- web vitest: 178 passed, 9 skipped. `TrackTile › Public Premium
(non-owner)` timed out once while the machine was under heavy load, then
passed 3 out of 3 when run alone.

## Verification matrix (before the rebase; see the bottom for the
rebased stack)
| | iOS 26.5 sim (Release) | iOS 27 sim (Release) | Android API 36 emu
(prodRelease, arm64) |
|---|---|---|---|
| Build | ✅ Xcode 27, `generic/platform=iOS Simulator` | same binary | ✅
debug keystore |
| Old arch at runtime | ✅ JS thread `com.facebook.react.JavaScript` | –
| ✅ `ReactRootView` + "Legacy Architecture" warning |
| Launch past splash | ✅ | ✅ | ✅ `assets://index.android.bundle` |
| Sign-up / sign-in screens | (signed in) | ✅ | ✅ including Create
Password |
| Signed-in feed, scroll | ✅ | – | – |
| Playback + now playing drawer (open, drag closed) | ✅ | – | – |
| Background → foreground while playing | ✅ audio kept going (0:09 →
0:41) | – | – |
| Search | ✅ | – | – |
| Profile: collapsible header + tab swipe | ✅ | – | – |
| Deep link, warm | ✅ `audius://audius` | ✅ link delivered | – |
| Deep link, cold | ✅ `audius://deadmau5` | ✅ (signed out → sign-on) | –
|
| Hardware Back | – | – | ✅ pops Create Password; at root backgrounds
the app without killing it |
| Sign-on footer above nav bar | – | – | ✅ |
| Red JS errors | none, apart from a recurring `JSON Parse error:
Unexpected character: <` (not yet traced) | none | none |

The CodePush folder was moved aside or cleared before every cold launch,
so all results above are from the bundled JS.

## Still needs a real device
- background audio with the screen locked for more than 2 minutes
- lock-screen and notification controls
- Chromecast
- push notifications

## Notes
- A Release build that downloads a production OTA built for 1.5.186 or
1.5.187 runs a 0.79 bundle on a 0.81 binary. 1.5.188 ships with its own
package.json version (#14654) so it never receives those OTAs.
- The Hermes `ExceptionsManager` fix now applies through patch-package
(#14643), renamed for 0.81.6 above.

## Verification of the rebased stack (2026-10-08)
Built from a local, unpushed integration branch: #14652's tip (which
contains #14647) merged with #14651, on top of #14654.

| Check | Result |
|---|---|
| `npx tsc --noEmit -p packages/mobile` | pass |
| eslint on the touched files / `turbo run verify` lint | pass (1
existing warning in `HostRemixContestDrawer.tsx`) |
| `cd packages/mobile && npm test` | 9 suites, 34 tests pass |
| iOS Release, `generic/platform=iOS Simulator`, arm64,
`ENVFILE=.env.prod` | builds; Info.plist 1.1.201,
`RCTNewArchEnabled=false`; bundle carries 1.5.188 |
| Android `assembleProdRelease`, arm64-v8a, debug keystore | builds;
versionName 1.1.537 |
| iOS 26.5 sim, installed over the signed-in app, CodePush moved aside |
launch to feed; JS thread `com.facebook.react.JavaScript` (old arch) |
| Playback from the 2nd feed track | plays; play bar tracker moves |
| Auto-advance | seek to 2:43/2:45 on track 2, advanced to track 3 |
| Now playing drawer | opens, scrubber advances, tap-to-seek works |
| Profile tabs | swipe Tracks → Albums, tap Reposts |
| notifee/RNFB APNs token | a temporary console log (not committed,
rebuilt without it afterwards) printed an 80-byte lowercase APNs token
at startup |
| Android 16 emulator, `pm clear` | `Loading JS bundle from
"assets://index.android.bundle"`, "Legacy Architecture" warning, sign-up
and sign-in screens render |
| Android hardware Back | **not verified**: the emulator's system_server
was killed by its watchdog three times under host load, so Back never
got a clean run |
| JS errors on iOS | only `Could not cache profile images` (content node
timeout) |

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
dylanjeffers added a commit that referenced this pull request Oct 9, 2026
## Summary

Version bump for native release **1.5.188**. Merging it starts the RC
and production native builds.

- `packages/mobile/package.json`: 1.5.187 → 1.5.188 (and the matching
`package-lock.json` entry)
- iOS `CFBundleShortVersionString`: 1.1.200 → 1.1.201
- Android `versionName`: 1.1.536 → 1.1.537

1.5.188 contains (all still on the old architecture):
- #14642: React Native 0.79.5 → 0.81.6, React 19.1.4 monorepo-wide
- #14647: RNTP 4.1.2 patch for bridgeless events and `Unit` module
methods (no change on old arch)
- #14651: playback progress and eq bars on the native driver
- #14652: react-native-svg 15.15.1 and the Lottie `shouldBeRecycled NO`
patch (no change on old arch)

1.5.189 is then only the new-architecture flag flip.

## Stack

```
main
└── chore/mobile-native-release-1.5.188   (this PR)
    └── chore/mobile-rn-0.81              #14642
        ├── fix/mobile-rntp-bridgeless    #14647
        │   └── fix/mobile-new-arch-prereqs  #14652
        └── fix/mobile-native-driver-progress  #14651
```

## Verification of the rebased stack (2026-10-08)
Built from a local, unpushed integration branch: #14652's tip (which
contains #14647) merged with #14651, on top of #14654.

| Check | Result |
|---|---|
| `npx tsc --noEmit -p packages/mobile` | pass |
| eslint on the touched files / `turbo run verify` lint | pass (1
existing warning in `HostRemixContestDrawer.tsx`) |
| `cd packages/mobile && npm test` | 9 suites, 34 tests pass |
| iOS Release, `generic/platform=iOS Simulator`, arm64,
`ENVFILE=.env.prod` | builds; Info.plist 1.1.201,
`RCTNewArchEnabled=false`; bundle carries 1.5.188 |
| Android `assembleProdRelease`, arm64-v8a, debug keystore | builds;
versionName 1.1.537 |
| iOS 26.5 sim, installed over the signed-in app, CodePush moved aside |
launch to feed; JS thread `com.facebook.react.JavaScript` (old arch) |
| Playback from the 2nd feed track | plays; play bar tracker moves |
| Auto-advance | seek to 2:43/2:45 on track 2, advanced to track 3 |
| Now playing drawer | opens, scrubber advances, tap-to-seek works |
| Profile tabs | swipe Tracks → Albums, tap Reposts |
| notifee/RNFB APNs token | a temporary console log (not committed,
rebuilt without it afterwards) printed an 80-byte lowercase APNs token
at startup |
| Android 16 emulator, `pm clear` | `Loading JS bundle from
"assets://index.android.bundle"`, "Legacy Architecture" warning, sign-up
and sign-in screens render |
| Android hardware Back | **not verified**: the emulator's system_server
was killed by its watchdog three times under host load, so Back never
got a clean run |
| JS errors on iOS | only `Could not cache profile images` (content node
timeout) |

## Merge order

1. **Wait until 1.5.187 is live in both stores.** Until then, any native
change on main would go into a 1.5.187 rebuild.
2. **Dispatch a production OTA from main before merging anything
below**, for every store version that can run main's JS:
   ```
gh workflow run mobile.yml --repo AudiusProject/apps --ref main -f
ota_channel=production
   ```
With main at 1.5.187 this publishes to `production/1.5.187`. **Do not**
dispatch `-f binary_version=1.5.186` or `1.5.185` from main any more:
main now carries #14627, which calls
`TurboModuleRegistry.getEnforcing('ReactNativeFs')` at import, so that
JS crashes 1.5.186 and older binaries. If 1.5.186 users still need a
fix, dispatch from a commit before 5c4ee7e.
3. **Land everything on main in one push.** Merge the stack into this
branch from the top down: #14652 into #14647, #14647 and #14651 into
#14642, #14642 into this branch. Then merge this PR into main. Any push
to main that leaves the version unchanged publishes an RC OTA to the
current binary's history, and RN 0.81 JS on a 0.79 binary will not
start. With one push that also changes the version, the version check
skips the OTA and starts the native builds. After that, OTAs route to
`1.5.188` histories.
4. **Device-test the RC builds before submitting:**
- cold launch on both platforms, old arch at runtime (iOS JS thread
`com.facebook.react.JavaScript`; Android "Legacy Architecture" warning)
   - background audio with the screen locked for more than 2 minutes
   - lock-screen and notification controls, Bluetooth, Chromecast
- auto-advance, including starting from the 2nd track of a list
(#14649/#14650)
- play bar and scrubber position: seek, drag, pause/resume, background
then foreground
   - first play does not pause itself (Lottie)
- push: token registered after the 1.5.187 → 1.5.188 update and taps
open the right screen (#14640)
   - Android hardware Back on a pushed screen and at the root
   - gradients and offline downloads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
dylanjeffers added a commit that referenced this pull request Oct 9, 2026
…sent (#14659)

Web Build on main fails on a node_modules cache hit:

```
Error: Patch file found for package lottie-react-native which is not present at node_modules/lottie-react-native
```

The Lottie patch from #14652 lives in
`packages/mobile/workspace-patches` because npm nests that package under
`packages/mobile/node_modules`. web.yml's cache doesn't include that
folder, so on a cache hit the package is missing and `--error-on-fail`
exits. The mobile workflow caches the folder, so mobile builds are
unaffected.

The step now runs only when `packages/mobile/node_modules` exists. Full
installs still apply the patch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant