fix(ios): align expo module set to SDK 57.0.8 and gate dyld symbols - #425
Closed
RonenMars wants to merge 1 commit into
Closed
fix(ios): align expo module set to SDK 57.0.8 and gate dyld symbols#425RonenMars wants to merge 1 commit into
RonenMars wants to merge 1 commit into
Conversation
Build 173 crashed at launch on every device with EXC_CRASH (SIGABRT) / "DYLD 4 Symbol missing": ExpoCamera 57.0.1 referenced AnyModule._decorateExpoObject(object:in:appContext:), but the bundled ExpoModulesCore 57.0.7 renamed that protocol requirement to the two-argument _decorateModule(object:in:). The skew came from #412, which pinned expo-modules-core forward to 57.0.7 via npm overrides to get ColorCompat for the Android R8 minify step, without moving the rest of the Expo module set with it. ExpoModulesCore ships as a precompiled xcframework, so the mismatch was invisible at compile time and only surfaced in dyld. Bump expo to 57.0.8 and align all 22 expo-*/@expo/* modules to that SDK's bundled native module set, which supplies expo-modules-core 57.0.7 legitimately and moves expo-camera to 57.0.3. The override is now redundant and is removed; the Android ColorCompat fix is preserved because core stays at 57.0.7. Also bump react-native-screens to 4.26.2 to match what expo-router 57.0.8 requires, removing a duplicate nested copy. expo-image-manipulator was still on 57.0.1 and referenced the same missing symbol, so the original fix was incomplete. Add two guardrails, both verified against a real Release build: - scripts/verify-dyld-symbols.sh resolves every cross-framework symbol in the archive before altool upload, so a launch-crashing build cannot reach TestFlight. - npm run check:native-deps fails CI on duplicate native modules, which is the npm-level shape of this bug.
This was referenced Jul 25, 2026
RonenMars
added a commit
that referenced
this pull request
Jul 26, 2026
The integration branch has never been run through test.yml, so three failures accumulated unnoticed across ~82 commits. PR #425 was the first thing to trigger CI on it, which surfaced them. Type check and Integration tests both traced to app/conversation/[id].tsx. a1e263c added LivePauseControl to the header actions and, in resolving that conflict, deleted the in-chat search Pressable that ff28c60 had introduced, while leaving the MagnifyingGlass import, the headerButton styles, the searchBarState hook, and the test coverage all in place. The same commit also dropped the makeSearchStyles import while keeping its call site, which is the TS2552 error. Restore both: the import and the search button, verbatim from a1e263c's parent. i18n unused keys flagged three keys with no remaining code reference. b75dfb8 pruned connect.step1 and connect.step2 as dead, but ConnectStep.tsx still renders all three steps as a numbered sequence, so step3 rendered alone after a gap. Restore step1 and step2 in all four locales from their pre-prune text. Drop onboarding.connect.footnote and servers.dialog.removeDismiss, which are genuinely unreferenced. conversation.search.open is left as-is: it labels the restored search button, so it was never dead.
RonenMars
added a commit
that referenced
this pull request
Jul 28, 2026
The integration branch has never been run through test.yml, so three failures accumulated unnoticed across ~82 commits. PR #425 was the first thing to trigger CI on it, which surfaced them. Type check and Integration tests both traced to app/conversation/[id].tsx. a1e263c added LivePauseControl to the header actions and, in resolving that conflict, deleted the in-chat search Pressable that ff28c60 had introduced, while leaving the MagnifyingGlass import, the headerButton styles, the searchBarState hook, and the test coverage all in place. The same commit also dropped the makeSearchStyles import while keeping its call site, which is the TS2552 error. Restore both: the import and the search button, verbatim from a1e263c's parent. i18n unused keys flagged three keys with no remaining code reference. b75dfb8 pruned connect.step1 and connect.step2 as dead, but ConnectStep.tsx still renders all three steps as a numbered sequence, so step3 rendered alone after a gap. Restore step1 and step2 in all four locales from their pre-prune text. Drop onboarding.connect.footnote and servers.dialog.removeDismiss, which are genuinely unreferenced. conversation.search.open is left as-is: it labels the restored search button, so it was never dead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TestFlight build 173 crashed at launch on every device with
EXC_CRASH (SIGABRT)/Termination Reason: DYLD 4 Symbol missing.ExpoCamera57.0.1 referencedAnyModule._decorateExpoObject(object:in:appContext:), but the bundledExpoModulesCore57.0.7 renamed that protocol requirement to the two-argument_decorateModule(object:in:), so dyld aborted before any app code ran.The skew came from #412, which pinned
expo-modules-coreforward to 57.0.7 via npmoverridesto getColorCompatfor the Android R8 minify step, without moving the rest of the Expo module set with it.ExpoModulesCoreships as a precompiled xcframework, so the mismatch was invisible at compile time and surfaced only in dyld — which is why CI went green and the iOS ship job succeeded.The third item on #412's own test plan ("Smoke-check iOS build still links after ExpoModulesCore 57.0.7 pod bump") is the one that would have caught it.
Changes
expoto 57.0.8 and align all 22expo-*/@expo/*modules to that SDK's bundled native module set.That supplies
expo-modules-core57.0.7 legitimately and movesexpo-camerato 57.0.3.expo-modules-coreoverride.The Android
ColorCompatfix from fix(android): pin expo-modules-core for R8 ColorCompat #412 is preserved because core still resolves to 57.0.7.react-native-screensto 4.26.2 to match whatexpo-router57.0.8 requires, removing a duplicate nested copy.expo-image-manipulatorwas still on 57.0.1 and referenced the same missing symbol, so a first pass that only fixedexpo-camerawas incomplete.Guardrails
scripts/verify-dyld-symbols.shresolves every cross-framework symbol in the exported archive before thealtoolupload, so a launch-crashing build cannot reach TestFlight.It runs in both the local and CI ship paths via
archive-and-upload.sh.npm run check:native-deps(newNative depsCI job) fails on duplicate native modules, which is the npm-level shape of this bug.Both were validated in each direction: they pass on a good build and fail on the real defect.
The symbol check is what surfaced the
expo-image-manipulatorbreakage.Test plan
generic/platform=iOSsucceedsverify-dyld-symbols.shreports all 637 cross-framework symbols resolving on that buildverify-dyld-symbols.shfails when a bundled export is renamed (simulated 173 skew)check:native-depspasses on the aligned tree and fails on a reintroduced duplicatef2242bc4— pre-existing, in files this PR does not touchf2242bc4— pre-existingNotes
react-native-get-random-valuessits at 2.0.0 while SDK 57.0.8 wants~1.11.0.Left as-is: it is a deliberate pin from #332, is not ABI-coupled to
expo-modules-core, and the Release build links clean.The lockfile regeneration surfaced that pre-existing drift rather than introducing it.
Dependabot #415 (
expo-image-picker→ 57.0.6), #414 (expo-font→ 57.0.1), and #353 (shell-quote→ 1.10.0) are subsumed by this branch and can be closed.#413 (
babel-preset-expo) and #291 (typescript7) are unaffected and still stand on their own.Build 173 should be pulled from TestFlight once a replacement is up.