# External binaryTarget dependency update fails to compile without Xcode Clean

**URL:** <https://community.tuist.dev/t/external-binarytarget-dependency-update-fails-to-compile-without-xcode-clean/991>\
**Category:** Troubleshooting & how to\
**Created:** [June 5, 2026, 9:07pm UTC](https://community.tuist.dev/t/external-binarytarget-dependency-update-fails-to-compile-without-xcode-clean/991 "2026-06-05T21:07:08Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ceichin-peya](https://community.tuist.dev/user_avatar/community.tuist.dev/ceichin-peya/32/936_2.png) [@ceichin-peya](https://community.tuist.dev/u/ceichin-peya)\
**Post date:** [June 5, 2026, 9:07pm UTC](https://community.tuist.dev/t/external-binarytarget-dependency-update-fails-to-compile-without-xcode-clean/991/1 "2026-06-05T21:07:08Z")

</div>

**Steps to reproduce:**

1. Run `tuist init`

2. In `Tuist/Package.swift`, add:

`.package(url: "`[https://github.com/getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa)`", exact: "9.16.1")`

3. In `Project.swift`, add the dependency to the main target:

`dependencies: [.external(name: "Sentry")]`

4. Run `tuist install`

5. Run `tuist generate`

6. In Xcode, add the following code:

```swift
import Sentry

// Add this somewhere:
SentrySDK.start { options in }

```

7. In Xcode press `Cmd+B` → **Builds OK** ✅

8. Downgrade the version in `Tuist/Package.swift` to `exact: "8.58.3"`

9. Run `tuist install`

10. Run `tuist generate`

11. In Xcode press `Cmd+B` → **Build Fails** ❌

**BUT:** If I do an Xcode Clean at this point, it builds fine.

**Expected behavior:**

After running `tuist install` and `tuist generate` with the updated version, Xcode should build successfully without requiring a manual clean.

**Environment:**

Tuist version: 4.196.0

Thanks!

---

<div class="post-metadata">

**Author:** ![marekfort](https://community.tuist.dev/user_avatar/community.tuist.dev/marekfort/32/8_2.png) [@marekfort](https://community.tuist.dev/u/marekfort)\
**Post date:** [June 9, 2026, 4:11pm UTC](https://community.tuist.dev/t/external-binarytarget-dependency-update-fails-to-compile-without-xcode-clean/991/2 "2026-06-09T16:11:13Z")

</div>

Hey!

Can you provide a reproducible sample and provide us with the exact Xcode versions? I wasn’t able to reproduce the issue on our side based on this description.

---

<div class="post-metadata">

**Author:** ![marekfort](https://community.tuist.dev/user_avatar/community.tuist.dev/marekfort/32/8_2.png) [@marekfort](https://community.tuist.dev/u/marekfort)\
**Post date:** [June 10, 2026, 8:46am UTC](https://community.tuist.dev/t/external-binarytarget-dependency-update-fails-to-compile-without-xcode-clean/991/3 "2026-06-10T08:46:16Z")

</div>

I was able to reproduce the issue deterministically now, and the short version is: **this is an Xcode bug, not a Tuist one.** It reproduces with plain SwiftPM and no Tuist involved.

### Reproduction

On Xcode 26.5 + Tuist 4.196.0, the failure is reliable once you go _back and forth_ between the two versions:

```auto
clean build @ Sentry 8.58.3 → ✅switch → 9.16.1, tuist install + generate, build → ✅switch → 8.58.3, tuist install + generate, build → ❌ missing required module 'CommonCrypto'

```

The failing step is always the **downgrade** , and only after at least two switches. A single switch, or starting clean on 9.16.1, doesn’t trigger it, which lines up with your observation that it worked at first and then started happening after toggling a few times.

### What’s actually going on

It’s Xcode’s **explicit modules** incremental build reusing a stale precompiled module from the module cache:

- Sentry 9.16.1’s `Sentry.swiftinterface` does `import CommonCrypto`. 8.58.3’s does not (their `module.modulemap` differs too).
- After you downgrade, the explicit module map Xcode hands to the Swift frontend correctly contains **no** `CommonCrypto` entry, but it still points `Sentry` at a precompiled `Sentry-*.swiftmodule` left over from the 9.16.1 build that _still_ records a requirement on `CommonCrypto` (and `SwiftUI`). The frontend can’t satisfy it, so you get `missing required module 'CommonCrypto'`.
- Because the binary `xcframework` is vendored at a version-independent path, the framework search path never changes across versions, so Xcode’s scanner doesn’t re-derive the module and the stale one sticks around until you Clean.

### Why it’s not Tuist

I built a tiny vanilla SwiftPM package with the same Sentry binary dependency and no Tuist at all, then ran the exact same back-and-forth via `xcodebuild`. It fails identically (`missing required modules: 'CommonCrypto', 'SwiftUI'`). Native SwiftPM vendors binary artifacts at the same kind of stable path, so it hits the same cache staleness. I’d recommend filing this with Apple as an Xcode explicit-modules / binary-target incremental-build bug.

### Workarounds

All three of these resolve it, verified:

1. **Xcode Clean** (what you’re doing today).
2. You don’t actually need a full Clean. Wiping just the module cache is enough:

```auto
rm -rf <DerivedData>/Build/Intermediates.noindex/SwiftExplicitPrecompiledModulesrm -rf <DerivedData>/ModuleCache.noindex

```

1. The cleanest one for CI: **disable explicit modules** by setting `SWIFT_ENABLE_EXPLICIT_MODULES=NO`. With that, the full back-and-forth sequence builds end to end with no clean. You can set it as a build setting in your `Project.swift` on the affected target(s). The tradeoff is you lose the explicit-modules build-performance improvements, but it sidesteps the cache bug.

Hope that unblocks your CI. Happy to help wire up option 3 in the project if useful.

_note: answer generated by Claude_
