From 0478190113ca3e814e227bb1c09b42f6557805c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Rolka?= Date: Thu, 21 May 2026 12:50:37 +0200 Subject: [PATCH 1/2] add troubleshooting about metro Invariant Violation --- TROUBLESHOOTING.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index 2f9bc534..655d1864 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -276,4 +276,64 @@ To fix this, you need to exclude the `.rnrepo-cache` directories from Expo's fin See the [`.fingerprintignore` documentation](https://docs.expo.dev/versions/latest/sdk/fingerprint/#fingerprintignore) or [`fingerprint.config.js` documentation](https://docs.expo.dev/versions/latest/sdk/fingerprint/#fingerprintconfigjs) for more details. +### Metro `Invariant Violation` for `.rnrepo-cache` Directory + +#### Problem Description +After running `pod install`, Metro may crash with an `Invariant Violation` error when it detects a change inside the `.rnrepo-cache` directory created by the RNRepo plugin: + +``` +Invariant Violation: Detected addition or modification of file node_modules/react-native-screens/.rnrepo-cache/Current, but it is tracked as a non-empty directory +... +``` + +This happens because Metro's `TreeFS` initially sees `.rnrepo-cache/Current` as a directory (it is an Xcode-style symlink pointing to the currently active xcframework version) and then receives a filesystem event that treats it as a file. The mismatch causes Metro to throw. + +#### Solution +Cleaning metro/watchman cache usually helps: + +```bash +npx watchman watch-del-all +npx metro restart --reset-cache # or for expo: npx expo start -c +``` + +But if issue still persist, you can exclude the `.rnrepo-cache` directories from Metro's file watcher by adding them to the `blockList` in your `metro.config.js`: + +```js +// metro.config.js +const { getDefaultConfig } = require('expo/metro-config'); + +const config = getDefaultConfig(__dirname); + +const rnRepoCachePattern = /.*\.rnrepo-cache.*/; + +if (config.resolver.blockList) { + if (Array.isArray(config.resolver.blockList)) { + config.resolver.blockList.push(rnRepoCachePattern); + } else { + config.resolver.blockList = [config.resolver.blockList, rnRepoCachePattern]; + } +} else { + // older Expo/Metro versions + config.resolver.blacklistRE = rnRepoCachePattern; + config.resolver.blockList = [rnRepoCachePattern]; +} + +module.exports = config; +``` + +For bare React Native projects (without Expo), use `@react-native/metro-config` instead: + +```js +// metro.config.js +const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); + +const config = { + resolver: { + blockList: [/.*\.rnrepo-cache.*/], + }, +}; + +module.exports = mergeConfig(getDefaultConfig(__dirname), config); +``` + --- From 9f3accbaefcbef7a3accd575fa74758896510929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Rolka?= Date: Fri, 22 May 2026 15:02:01 +0200 Subject: [PATCH 2/2] remove excluding from metro snippets --- TROUBLESHOOTING.md | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index 655d1864..72744825 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -298,42 +298,4 @@ npx metro restart --reset-cache # or for expo: npx expo start -c But if issue still persist, you can exclude the `.rnrepo-cache` directories from Metro's file watcher by adding them to the `blockList` in your `metro.config.js`: -```js -// metro.config.js -const { getDefaultConfig } = require('expo/metro-config'); - -const config = getDefaultConfig(__dirname); - -const rnRepoCachePattern = /.*\.rnrepo-cache.*/; - -if (config.resolver.blockList) { - if (Array.isArray(config.resolver.blockList)) { - config.resolver.blockList.push(rnRepoCachePattern); - } else { - config.resolver.blockList = [config.resolver.blockList, rnRepoCachePattern]; - } -} else { - // older Expo/Metro versions - config.resolver.blacklistRE = rnRepoCachePattern; - config.resolver.blockList = [rnRepoCachePattern]; -} - -module.exports = config; -``` - -For bare React Native projects (without Expo), use `@react-native/metro-config` instead: - -```js -// metro.config.js -const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); - -const config = { - resolver: { - blockList: [/.*\.rnrepo-cache.*/], - }, -}; - -module.exports = mergeConfig(getDefaultConfig(__dirname), config); -``` - ---