MetaMask / MetaMask/metamask-mobile
CXX1210: Hermes prefab not found — reproducible build failure in v7.76.0 (RN 0.76.9 + New Architecture)
- Dominant language
- TypeScript
- Stars
- 3k
- Forks
- 1.7k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 669
Description
### What is this about?
Hi MetaMask team!
We're from [WalletScrutiny](https://walletscrutiny.com), a project that verifies whether cryptocurrency wallets can be built reproducibly from source. We attempted to build MetaMask Android **v7.76.0** from source and ran into a consistent build failure we'd like to report and discuss.
## The Error
Every build attempt fails during Gradle's cmake configuration phase:
```
> Task :react-native:packages:react-native:ReactAndroid:configureCMakeRelWithDebInfo[arm64-v8a] FAILED
Caused by: com.android.builder.errors.EvalIssueException:
[CXX1210] .../node_modules/react-native/ReactAndroid/src/main/jni/CMakeLists.txt
release|arm64-v8a : No compatible library found
```
This happens for all four ABIs. The build takes ~20 minutes before failing (yarn install and repository setup complete successfully; the failure is at native CMake configuration).
## Root Cause Identified
After extensive diagnosis, we traced this to `.yarn/patches/react-native-patch-d76d50a92f.patch`, which MetaMask applies during `yarn install`. This patch modifies `ReactAndroid/build.gradle.kts` inside the `react-native` package:
```kotlin
// After MetaMask's Yarn patch is applied — ReactAndroid/build.gradle.kts line ~655:
// It's up to the consumer to decide if hermes should be included or not.
// Therefore hermes-engine is a compileOnly dependency.
compileOnly("com.facebook.react:hermes-android:0.76.9")
```
The problem: **AGP does not extract prefab packages for `compileOnly` dependencies in library modules.**
Prefab is the mechanism that allows cmake to find C/C++ libraries via `find_package()`. AGP only unpacks prefab content for `implementation`, `api`, and `runtimeOnly` configurations — not `compileOnly`. With hermes declared as `compileOnly` inside ReactAndroid (a library module), AGP never extracts the hermes AAR's prefab directory into the cmake search path (`.cxx/*/prefab/`), so cmake's `find_package(hermes-engine REQUIRED CONFIG)` finds nothing and throws CXX1210.
## Environment
| Component | Version |
|-----------|---------|
| MetaMask version | 7.76.0 (tag `v7.76.0`, commit `a9b520593aa735b2f5a8718887977e6a34128e62`) |
| React Native | 0.76.9 |
| Architecture | New Architecture (Fabric + TurboModules) |
| Android SDK | 35 |
| NDK | 26.1.10909125 |
| AGP | 8.6.0 (from Gradle wrapper) |
| Java | OpenJDK 17 |
| Build command | `./gradlew bundleProdRelease` |
| Host OS | Debian 12 Bookworm (Docker container) |
## Fix Attempted
We applied a sed patch after `yarn install` to change the dependency scope:
```bash
sed -i 's/compileOnly("com.facebook.react:hermes-android:/api("com.facebook.react:hermes-android:/' \
node_modules/react-native/ReactAndroid/build.gradle.kts
```
Diagnostic output confirmed the patch applied (`compileOnly` → `api` on line 657). In at least one run, this allowed cmake to proceed — the build reached `:app:bundleProdReleaseResources` before being interrupted. However, the fix was not stable across runs, suggesting an additional environmental factor we have not yet isolated.
We also tried adding `prefab = true` to the `buildFeatures {}` block in the same file, which is required for library modules to consume prefab packages in some AGP configurations.
## Questions for the MetaMask Team
1. **How does your Bitrise CI environment resolve hermes at the cmake level?** The Yarn patch comment says "It's up to the consumer to decide if hermes should be included or not." What does the "consumer" in your production build do to re-add hermes with the correct scope?
2. **Is there a `hermes-engine` dependency at the app module level** (in `android/app/build.gradle`) that your CI relies on, which forces AGP to extract the hermes prefab before ReactAndroid's cmake runs?
3. **Does your CI use `newArchEnabled=true` in `gradle.properties`?** We're using New Architecture as detected from the repository defaults — is the production build configuration different?
4. **Is there internal build documentation we may have missed?** We reviewed the README, CI YAML files, and `scripts/build.sh` but didn't find a guide for external reproducible builds.
## Context: WalletScrutiny Verification
We previously filed [a related issue for v7.61.6](https://github.com/MetaMask/metamask-mobile/issues) covering Boost/Hermes build failures. Since then, MetaMask upgraded to RN 0.76.9 with the New Architecture, and the failure mode shifted from Boost extraction to hermes prefab resolution. Progress has been made — the build now gets much further than before — but the CXX1210 issue is the remaining blocker.
We'll mark MetaMask v7.76.0 as `ftbfs` (failed to build from source) on WalletScrutiny until the build can be reproduced. We want MetaMask to succeed here — an open-source self-custody wallet that builds reproducibly is a strong security signal for users.
Any guidance on the expected build environment or how to replicate the consumer-level hermes setup would be very appreciated.
---
**WalletScrutiny:**
- Website: https://walletscrutiny.com
- MetaMask listing: https://walletscrutiny.com/android/io.metamask/
- Methodology: https://walletscrutiny.com/methodology/
### Scenario
_No response_
### Design
_No response_
### Technical Details
_No response_
### Threat Modeling Framework
_No response_
### Acceptance Criteria
_No response_
### Stakeholder review needed before the work gets merged
- [ ] Engineering (needed in most cases)
- [ ] Design
- [ ] Product
- [ ] QA (automation tests are required to pass before merging PRs but not all changes are covered by automation tests - please review if QA is needed beyond automation tests)
- [ ] Security
- [ ] Legal
- [ ] Marketing
- [ ] Management (please specify)
- [ ] Other (please specify)
### References
_No response_
Contributor guide
Research direction
Reproduce ./gradlew bundleProdRelease with the listed environment, then inspect .yarn/patches/react-native-patch-d76d50a92f.patch and node_modules/react-native/ReactAndroid/build.gradle.kts around the hermes-android dependency. Check android/app/build.gradle, gradle.properties, and scripts/build.sh for consumer-level Hermes configuration. Done means a clean source build resolves Hermes prefab for all ABIs without manual edits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, cmake, kotlin, react-native
- Domain
- build-system, mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100