authorgravatar for bompus@users.noreply.github.comAaron Queen <bompus@users.noreply.github.com> 2026-10-02 12:11:30-06:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-02 11:11:30-07:00
log42b5885c90bcef05ba56acce00cdd2cb9d4998b7
treecf8920e65636cdddacba1bd2dc0ab3709e2ba54b
parent6c8fed35dded9ff71c5b46807125457acbb76be6
signature Signed by PGP key B5690EEEBB952194

fix(mobile): opening a thread no longer crashes Android release builds (#14850)


2 files changed, 60 insertions(+), 12 deletions(-)

patches/react-native-keyboard-controller@1.22.4.patch+57-9
...@@ -188,7 +188,7 @@ index cecee07..533a9e9 100644...@@ -188,7 +188,7 @@ index cecee07..533a9e9 100644
188 padding,188 padding,
189 currentHeight,189 currentHeight,
190diff --git a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js190diff --git a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js
191index 54a1c57..19b44fc 100644191index 54a1c57..00c2941 100644
192--- a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js192--- a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js
193+++ b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js193+++ b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js
194@@ -31,6 +31,8 @@ function useExtraContentPadding(options) {194@@ -31,6 +31,8 @@ function useExtraContentPadding(options) {
...@@ -200,7 +200,23 @@ index 54a1c57..19b44fc 100644...@@ -200,7 +200,23 @@ index 54a1c57..19b44fc 100644
200 scroll,200 scroll,
201 layout,201 layout,
202 size,202 size,
203@@ -70,8 +72,8 @@ function useExtraContentPadding(options) {203@@ -50,8 +52,13 @@ function useExtraContentPadding(options) {
204 // otherwise the native ScrollView clamps to the old range.
205 requestAnimationFrame(() => {
206 // check that view is still mounted and ref is actual
207- // otherwise it may lead to a crash
208- if (!scrollViewRef()) {
209+ // otherwise it may lead to a crash. Reanimated 4.7+ passes the
210+ // ref to the UI runtime as a shareable holding the node in `.value`.
211+ const node =
212+ typeof scrollViewRef === "function"
213+ ? scrollViewRef()
214+ : scrollViewRef.value;
215+ if (!node) {
216 return;
217 }
218 (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, target, false);
219@@ -70,8 +77,8 @@ function useExtraContentPadding(options) {
204 }220 }
205 221
206 // Compute effective delta considering blankSpace floor222 // Compute effective delta considering blankSpace floor
...@@ -211,7 +227,7 @@ index 54a1c57..19b44fc 100644...@@ -211,7 +227,7 @@ index 54a1c57..19b44fc 100644
211 const effectiveDelta = currentTotal - previousTotal;227 const effectiveDelta = currentTotal - previousTotal;
212 if (effectiveDelta === 0) {228 if (effectiveDelta === 0) {
213 // blankSpace absorbed the change229 // blankSpace absorbed the change
214@@ -90,10 +92,11 @@ function useExtraContentPadding(options) {230@@ -90,10 +97,11 @@ function useExtraContentPadding(options) {
215 const target = Math.max(scroll.value - effectiveDelta, -currentTotal);231 const target = Math.max(scroll.value - effectiveDelta, -currentTotal);
216 scrollToTarget(target);232 scrollToTarget(target);
217 } else {233 } else {
...@@ -426,7 +442,7 @@ index 407275d..19427d7 100644...@@ -426,7 +442,7 @@ index 407275d..19427d7 100644
426 padding,442 padding,
427 currentHeight,443 currentHeight,
428diff --git a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js444diff --git a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js
429index 5885415..6e694fa 100644445index 5885415..8b3c4f0 100644
430--- a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js446--- a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js
431+++ b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js447+++ b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js
432@@ -25,6 +25,8 @@ function useExtraContentPadding(options) {448@@ -25,6 +25,8 @@ function useExtraContentPadding(options) {
...@@ -438,7 +454,23 @@ index 5885415..6e694fa 100644...@@ -438,7 +454,23 @@ index 5885415..6e694fa 100644
438 scroll,454 scroll,
439 layout,455 layout,
440 size,456 size,
441@@ -64,8 +66,8 @@ function useExtraContentPadding(options) {457@@ -44,8 +46,13 @@ function useExtraContentPadding(options) {
458 // otherwise the native ScrollView clamps to the old range.
459 requestAnimationFrame(() => {
460 // check that view is still mounted and ref is actual
461- // otherwise it may lead to a crash
462- if (!scrollViewRef()) {
463+ // otherwise it may lead to a crash. Reanimated 4.7+ passes the
464+ // ref to the UI runtime as a shareable holding the node in `.value`.
465+ const node =
466+ typeof scrollViewRef === "function"
467+ ? scrollViewRef()
468+ : scrollViewRef.value;
469+ if (!node) {
470 return;
471 }
472 scrollTo(scrollViewRef, 0, target, false);
473@@ -64,8 +71,8 @@ function useExtraContentPadding(options) {
442 }474 }
443 475
444 // Compute effective delta considering blankSpace floor476 // Compute effective delta considering blankSpace floor
...@@ -449,7 +481,7 @@ index 5885415..6e694fa 100644...@@ -449,7 +481,7 @@ index 5885415..6e694fa 100644
449 const effectiveDelta = currentTotal - previousTotal;481 const effectiveDelta = currentTotal - previousTotal;
450 if (effectiveDelta === 0) {482 if (effectiveDelta === 0) {
451 // blankSpace absorbed the change483 // blankSpace absorbed the change
452@@ -84,11 +86,12 @@ function useExtraContentPadding(options) {484@@ -84,11 +91,12 @@ function useExtraContentPadding(options) {
453 const target = Math.max(scroll.value - effectiveDelta, -currentTotal);485 const target = Math.max(scroll.value - effectiveDelta, -currentTotal);
454 scrollToTarget(target);486 scrollToTarget(target);
455 } else {487 } else {
...@@ -810,7 +842,7 @@ index 02abf5c..4ee0ddd 100644...@@ -810,7 +842,7 @@ index 02abf5c..4ee0ddd 100644
810 842
811 type UseChatKeyboardReturn = {843 type UseChatKeyboardReturn = {
812diff --git a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts844diff --git a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
813index c9c93f3..76a201d 100644845index c9c93f3..02f95c0 100644
814--- a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts846--- a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
815+++ b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts847+++ b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
816@@ -16,6 +16,10 @@ type UseExtraContentPaddingOptions = {848@@ -16,6 +16,10 @@ type UseExtraContentPaddingOptions = {
...@@ -833,7 +865,23 @@ index c9c93f3..76a201d 100644...@@ -833,7 +865,23 @@ index c9c93f3..76a201d 100644
833 scroll,865 scroll,
834 layout,866 layout,
835 size,867 size,
836@@ -99,14 +105,12 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void {868@@ -72,8 +78,13 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void {
869 // otherwise the native ScrollView clamps to the old range.
870 requestAnimationFrame(() => {
871 // check that view is still mounted and ref is actual
872- // otherwise it may lead to a crash
873- if (!scrollViewRef()) {
874+ // otherwise it may lead to a crash. Reanimated 4.7+ passes the
875+ // ref to the UI runtime as a shareable holding the node in `.value`.
876+ const node =
877+ typeof scrollViewRef === "function"
878+ ? scrollViewRef()
879+ : (scrollViewRef as unknown as { value: unknown }).value;
880+ if (!node) {
881 return;
882 }
883 scrollTo(scrollViewRef, 0, target, false);
884@@ -99,14 +110,12 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void {
837 }885 }
838 886
839 // Compute effective delta considering blankSpace floor887 // Compute effective delta considering blankSpace floor
...@@ -854,7 +902,7 @@ index c9c93f3..76a201d 100644...@@ -854,7 +902,7 @@ index c9c93f3..76a201d 100644
854 const effectiveDelta = currentTotal - previousTotal;902 const effectiveDelta = currentTotal - previousTotal;
855 903
856 if (effectiveDelta === 0) {904 if (effectiveDelta === 0) {
857@@ -139,16 +143,25 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void {905@@ -139,16 +148,25 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void {
858 906
859 scrollToTarget(target);907 scrollToTarget(target);
860 } else {908 } else {
pnpm-lock.yaml+3-3
...@@ -109,7 +109,7 @@ patchedDependencies:...@@ -109,7 +109,7 @@ patchedDependencies:
109 expo-widgets@58.0.11: 94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b109 expo-widgets@58.0.11: 94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b
110 node-pty@1.2.0-beta.15: f2fe901c61cde17986240002d05c172d5d0272d83ffaab8d0ebeb922763be414110 node-pty@1.2.0-beta.15: f2fe901c61cde17986240002d05c172d5d0272d83ffaab8d0ebeb922763be414
111 react-native-gesture-handler@3.2.1: d518a937e3cb2df5e7d67f1ab6b265c74a8639e4572d1b032b7b747e9b1c01a9111 react-native-gesture-handler@3.2.1: d518a937e3cb2df5e7d67f1ab6b265c74a8639e4572d1b032b7b747e9b1c01a9
112 react-native-keyboard-controller@1.22.4: a438114039aed2e280a81d95c25723132ad071e4768fe492bd92aa628ad74597112 react-native-keyboard-controller@1.22.4: c631278492f0113f42fa8bed43c7d8ed5779424dd12af0cefc55132c2ee1d84c
113 react-native-nitro-markdown@0.5.8: 642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c113 react-native-nitro-markdown@0.5.8: 642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c
114 react-native-nitro-modules@0.35.9: daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2114 react-native-nitro-modules@0.35.9: daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2
115 react-native-screens@4.28.0: cc1301436ee62c39860acc9ee1a1e60b7d47e6abd211c42effa62c056d165483115 react-native-screens@4.28.0: cc1301436ee62c39860acc9ee1a1e60b7d47e6abd211c42effa62c056d165483
...@@ -447,7 +447,7 @@ importers:...@@ -447,7 +447,7 @@ importers:
447 version: 0.2.2(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)447 version: 0.2.2(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)
448 react-native-keyboard-controller:448 react-native-keyboard-controller:
449 specifier: 1.22.4449 specifier: 1.22.4
450 version: 1.22.4(patch_hash=a438114039aed2e280a81d95c25723132ad071e4768fe492bd92aa628ad74597)(react-native-reanimated@4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)450 version: 1.22.4(patch_hash=c631278492f0113f42fa8bed43c7d8ed5779424dd12af0cefc55132c2ee1d84c)(react-native-reanimated@4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)
451 react-native-nitro-markdown:451 react-native-nitro-markdown:
452 specifier: ^0.5.0452 specifier: ^0.5.0
453 version: 0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)453 version: 0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)
...@@ -19853,7 +19853,7 @@ snapshots:...@@ -19853,7 +19853,7 @@ snapshots:
19853 react: 19.3.019853 react: 19.3.0
19854 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)19854 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)
1985519855
19856 react-native-keyboard-controller@1.22.4(patch_hash=a438114039aed2e280a81d95c25723132ad071e4768fe492bd92aa628ad74597)(react-native-reanimated@4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0):19856 react-native-keyboard-controller@1.22.4(patch_hash=c631278492f0113f42fa8bed43c7d8ed5779424dd12af0cefc55132c2ee1d84c)(react-native-reanimated@4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0):
19857 dependencies:19857 dependencies:
19858 react: 19.3.019858 react: 19.3.0
19859 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)19859 react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)