Pre-flight Checks
Bug Description
make expo-doctor always fails (exit 1) with the "Check that no duplicate dependencies are installed" check. Every duplicate reported is the same version of the same package, installed in multiple physical locations by Bun's workspace cache layout (node_modules/.bun/<pkg>@<version>+<hash>/...). Expo Doctor's autolinking duplicate check treats each cache copy as a distinct installation.
Steps to Reproduce
- Clone the repo and run
bun install at the workspace root
- Run
make expo-doctor (or cd apps/mobile && bunx expo-doctor)
- Observe:
20/21 checks passed. 1 checks failed and exit code 1
Expected Behavior
make expo-doctor passes (exit 0) when the only "duplicates" are the same-version copies created by the Bun cache layout, and fails only for real version conflicts.
Actual Behavior
Fails on duplicate detection for: @expo/ui, expo, expo-asset, expo-constants, expo-file-system, expo-font, expo-glass-effect, expo-linking, expo-symbols, react-native, @expo/dom-webview, @expo/fingerprint, @expo/log-box, expo-modules-core, expo-modules-jsi.
Example output:
✖ Check that no duplicate dependencies are installed
Found duplicates for expo:
├─ expo@56.0.18 (at: node_modules/expo)
│ └─ linked to: ../../node_modules/.bun/expo@56.0.18+b59826b516f43db8/node_modules/expo
├─ expo@56.0.18 (at: ../../node_modules/.bun/expo-keep-awake@56.0.3+4c7ef341795ca0da/node_modules/expo)
└─ expo@56.0.18 (at: ../../node_modules/.bun/expo-router@56.2.17+c5019fc39a4b1b18/node_modules/expo)
Impact
- The
expo-doctor Makefile target is effectively dead: it cannot pass on this repo
make check already works around it with $(MAKE) expo-doctor || echo "[WARN] expo-doctor checks failed (may be false positives from bun cache layout)" (Makefile ~line 859), so real regressions in this check are silently swallowed
EXPO_NO_DOCTOR=1 is exported in the Makefile (line 25) to bypass the same check during EAS local builds
Root Cause (analysis)
Bun hoists dependencies per-package into node_modules/.bun/ with content hashes. Expo Doctor's AutolinkingDependencyDuplicatesCheck scans native module resolutions and flags these same-version copies as duplicates. The check source includes a regex to ignore bun/pnpm cache paths (/node_modules[\\/]\.(?:bun|pnpm)[\\/]/), but the reported duplicates still surface — the ignore logic does not cover this Bun layout.
Possible Fix Directions (to evaluate when implementing)
- Dedup in Bun config:
bunfig.toml options (dedupe, linker = "hoisted" / isolated) to avoid same-version copies under .bun/
- Reinstall from scratch:
rm -rf node_modules apps/*/node_modules bun.lock* && bun install — verify duplicates persist
- Upstream: report to expo-doctor that the
.bun cache-layout ignore regex is insufficient (expo-doctor 1.20.1 is the latest at time of writing)
- Makefile: if upstream can't fix, make the target skip only the duplicate-deps check explicitly rather than swallowing all failures with
|| echo
Environment
- Bun: 1.3.14
- expo-doctor: 1.20.1
- Expo SDK: 56 (
expo@56.0.18), expo-router 56.2.17
- OS: Linux (Fedora Silverblue / distrobox)
Pre-flight Checks
Bug Description
make expo-doctoralways fails (exit 1) with the "Check that no duplicate dependencies are installed" check. Every duplicate reported is the same version of the same package, installed in multiple physical locations by Bun's workspace cache layout (node_modules/.bun/<pkg>@<version>+<hash>/...). Expo Doctor's autolinking duplicate check treats each cache copy as a distinct installation.Steps to Reproduce
bun installat the workspace rootmake expo-doctor(orcd apps/mobile && bunx expo-doctor)20/21 checks passed. 1 checks failedand exit code 1Expected Behavior
make expo-doctorpasses (exit 0) when the only "duplicates" are the same-version copies created by the Bun cache layout, and fails only for real version conflicts.Actual Behavior
Fails on duplicate detection for:
@expo/ui,expo,expo-asset,expo-constants,expo-file-system,expo-font,expo-glass-effect,expo-linking,expo-symbols,react-native,@expo/dom-webview,@expo/fingerprint,@expo/log-box,expo-modules-core,expo-modules-jsi.Example output:
Impact
expo-doctorMakefile target is effectively dead: it cannot pass on this repomake checkalready works around it with$(MAKE) expo-doctor || echo "[WARN] expo-doctor checks failed (may be false positives from bun cache layout)"(Makefile ~line 859), so real regressions in this check are silently swallowedEXPO_NO_DOCTOR=1is exported in the Makefile (line 25) to bypass the same check during EAS local buildsRoot Cause (analysis)
Bun hoists dependencies per-package into
node_modules/.bun/with content hashes. Expo Doctor'sAutolinkingDependencyDuplicatesCheckscans native module resolutions and flags these same-version copies as duplicates. The check source includes a regex to ignore bun/pnpm cache paths (/node_modules[\\/]\.(?:bun|pnpm)[\\/]/), but the reported duplicates still surface — the ignore logic does not cover this Bun layout.Possible Fix Directions (to evaluate when implementing)
bunfig.tomloptions (dedupe,linker = "hoisted"/isolated) to avoid same-version copies under.bun/rm -rf node_modules apps/*/node_modules bun.lock* && bun install— verify duplicates persist.buncache-layout ignore regex is insufficient (expo-doctor 1.20.1 is the latest at time of writing)|| echoEnvironment
expo@56.0.18), expo-router 56.2.17