Skip to content

fix(mobile): Android OTAs no longer reach builds missing their native code - #20174

Closed
shivamhwp wants to merge 1 commit into
pingdotgg:mainfrom
shivamhwp:t3android/issue-20170
Closed

shivamhwp wants to merge 1 commit into
pingdotgg:mainfrom
shivamhwp:t3android/issue-20170

Conversation

@shivamhwp

@shivamhwp shivamhwp commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #20170

Problem

Android beta 2.0.0 (93) crashes as soon as you tap Settings:

Can't find ViewManager 'ViewManagerAdapter_ExpoUI_TopAppBarView'

Build 93 was cut at 18:52 UTC on Oct 15, with Android fingerprint 035e46c0. At 22:47 UTC, #19994 and #19995 added a native TopAppBarView to our @expo/ui patch and started using it on Android screens. The Android fingerprint didn't change, so CI shipped that JS as an OTA to build 93, which has no TopAppBarView. The same thing happened again at 00:10 UTC.

The fingerprint didn't change because it contains no Expo native modules at all. @expo/fingerprint 0.21.5 calls path.relative(root, plugin.sourceDir) on every Expo Gradle plugin. expo-widgets declares a Maven-only plugin (io.github.expo.peek.glance-fork) with no sourceDir, so that call throws. A bare catch {} then returns [] for the whole Expo Android section. This has been broken since the SDK 58 upgrade brought in expo-widgets' Maven-only plugin, and every native change to an Expo module on Android (including our @expo/ui, expo-audio and expo-sharing patches) could ship as an OTA to binaries that don't have it. iOS is unaffected.

Fix

A pnpm patch for @expo/fingerprint@0.21.5 that skips Gradle plugins without a sourceDir. Their id, group and version are still hashed through expoAutolinkingConfig:android. The latest canary has the same bug, so there's no version to bump to.

Proof

Hashes from fingerprint:generate --platform android in apps/mobile with APP_VARIANT=production:

Expo Android sources Hash After editing @expo/ui/.../TopAppBarView.kt
main 0 2c6fe8a1 2c6fe8a1 (unchanged, so the OTA goes out)
this PR 57 f2c8e4fc 2d76558b (changed, so CI cuts a new build)

The iOS fingerprint is 15c773e0 with and without the patch.

Before: beta 93 on a POCO F4, tapping Settings

Full video

After

This PR changes how CI fingerprints builds, not the app, so there's no app build that shows the fix on a phone. Fork PRs also get no EXPO_TOKEN, so the EAS preview build skips. The proof is the fingerprint table above: on this branch, a native change to an Expo module now changes the runtime version, so CI cuts a build instead of shipping an OTA.

On a POCO M3, beta 93 installed over build 90 shows both sides. Its own embedded bundle (from before TopAppBar) opens Settings fine. Tapping T3 Account restarts the app into the pending bad OTA, which lands on the sign-in route and draws nothing. On this phone it's a blank screen instead of a crash, and it stays that way on reopen.

Full video

Note for maintainers

Merging this changes the Android fingerprint, so CI cuts a new Android build (the fingerprint already changed with #20067). Beta 93 users still have the crashing OTA until that build reaches them. Rolling runtime 035e46c0805270afe707381d97627b8ca606ecb4 back to its embedded bundle on the production channel would unbrick them right away. That bundle is from before TopAppBar.

Opus 5.5 via Claude Code, running in T3 Code.

🤖 Generated with Claude Code

…ve code

@expo/fingerprint 0.21.5 throws on expo-widgets' Maven-only Gradle plugin,
which has no sourceDir, and swallows the error. That dropped every Expo
native module from the Android fingerprint, so native patch changes such as
the @expo/ui TopAppBar view shipped as OTAs to older store builds.

Closes pingdotgg#20170

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shivamhwp shivamhwp added the 🚀 Mobile Continuous Deployment Trigger Expo preview build label Oct 16, 2026
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 16, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 2020d3d

Macroscope's review found this PR approvable — This is a focused Android fingerprinting bug fix that prevents native-module changes from being incorrectly treated as OTA-compatible, with only the corresponding build-versus-OTA decision affected. The dependency patch is explicitly wired into the workspace and lockfile without introducing new components, schemas, sensitive-area changes, or static-analysis overrides.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 12250beb-8742-4b90-a098-18c3928c38ea
📥 Commits

Reviewing files that changed from the base of the PR and between 2577baf and 2020d3d.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing: 2
  • patches/@expo__fingerprint@0.21.5.patch
  • pnpm-workspace.yaml

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

📝 Walkthrough

The Android Expo fingerprint scan now skips plugins whose sourceDir is not a string before computing a relative path. The workspace configuration registers the patch for @expo/fingerprint@0.21.5.

Changes: Android fingerprint source directory guard

Layer / File(s) Summary
Guard and patch registration
patches/@expo__fingerprint@0.21.5.patch, pnpm-workspace.yaml
The Android plugin scan skips entries with a non-string sourceDir before calling path.relative. The workspace configuration maps @expo/fingerprint@0.21.5 to this patch.

Priority: ⬆️ High

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 2020d

The patch addresses the Android fingerprint failure, with no identified merge-blocking issue.

### Architecture Summary

Architecture risk: 🔵 Low · up to 2020d

The change affects 2 systems.

Changed systems: patches, pnpm-workspace.yaml

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — patches (service) was modified; 1 changed file maps to changed impact.
  • observed — pnpm-workspace.yaml (service) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in patches/@expo__fingerprint@0.21.5.patch: The Android plugin loop now skips plugins without a string sourceDir before calling path.relative; plugins with a string sourceDir retain the existing handling.
  • observed — Modified behavior in pnpm-workspace.yaml: Adds the @expo/fingerprint@0.21.5 patched-dependency entry pointing to its patch file.
Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Linked Issues check Warning Issue #20170 requires that Android users can open Settings and sign in. The patch only changes future fingerprint generation by skipping Gradle plugins without sourceDir. The PR description states t… Provide a reviewed Android build or runtime bundle that contains the required native TopAppBarView support, or restore a compatible bundle for affected users. Verify that opening Settings and completing T3 Account sign-in no longer crashe…
Passed Passed checks: 3 passed
Check name Status Explanation
Out of Scope Changes check Passed The changes are limited to the @expo/fingerprint@0.21.5 patch and its pnpm-workspace.yaml mapping. They directly address the fingerprint failure that allowed incompatible Android native changes to…
Title check Passed The title is concise, uses a valid conventional-commit format, and clearly states the primary Android OTA safety fix.
Description check Passed The description explains the problem, root cause, fix, scope, verification results, user impact, workaround, and agent attribution. It links issue #20170 and provides detailed fingerprint evidence. Th…
Full details: Out of Scope Changes check

Explanation

The changes are limited to the @expo/fingerprint@0.21.5 patch and its pnpm-workspace.yaml mapping. They directly address the fingerprint failure that allowed incompatible Android native changes to ship as OTA updates. No unrelated change is shown.

Full details: Description check

Explanation

The description explains the problem, root cause, fix, scope, verification results, user impact, workaround, and agent attribution. It links issue #20170 and provides detailed fingerprint evidence. The template headings differ slightly, but the required information is present.

Full details: Linked Issues check

Explanation

Issue #20170 requires that Android users can open Settings and sign in. The patch only changes future fingerprint generation by skipping Gradle plugins without sourceDir. The PR description states that beta 93 still has the crashing OTA until a new build or rollback reaches users. The reviewed changes contain no app fix, compatible runtime bundle, or test that establishes successful sign-in on Android.

Resolution

Provide a reviewed Android build or runtime bundle that contains the required native TopAppBarView support, or restore a compatible bundle for affected users. Verify that opening Settings and completing T3 Account sign-in no longer crashes.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge

Copy link
Copy Markdown
Member

Note

Grok responding on behalf of Julius.

Closing this as superseded by #20384, which merged the same @expo/fingerprint patch (skipping Gradle plugins without a sourceDir) plus a workflow check that fails when a fingerprint hashes zero Expo native modules. Thanks for the thorough diagnosis and the before/after fingerprint table, it matched what we found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚀 Mobile Continuous Deployment Trigger Expo preview build size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Android beta 2.0.0 (93), crashes opening Settings / T3 Connect sign-in

2 participants