Background
I've got an external NVMe drive from which I boot macOS 27 + Xcode 27. On switching back to my macOS 26 boot partition, I started getting 5+ of these errors pop ups and need dismissing during each release builds:
“Xcode-27.0.0-Beta.6” is damaged and can’t be opened. You should move it to the Trash.
The annoying part is it means that it requires user interaction in the GUI to unblock the build process.
This is expected behavior when Xcode 27 is attempted to be launched from macOS 26. However, I was running these builds with Xcode 26.6 selected. I set claude to track down the process that was spawning this Xcode invocation and gatekeeper error modal. This is what it came back with, which seems entirely plausible.
Description
Crashlytics/upload-symbols locates Xcode by asking LaunchServices for every app registered with bundle identifier com.apple.dt.Xcode, then picks the candidate with the highest CoreSymbolicationDT.framework bundle version and dlopens DebugSymbolsDT / CoreSymbolicationDT out of it. It ignores which Xcode is actually selected (xcode-select / the DEVELOPER_DIR that Xcode itself exports into the run-script build phase).
This found the 27 Beta Xcode on the secondary boot volume, which makes upload-symbols load private frameworks from an Xcode that the running OS cannot use.
Reproduction steps
- Install two Xcodes where the newer one cannot run on the current OS — e.g. Xcode 26.6 in
/Applications and an Xcode 27 beta on another volume (/Volumes/macOS Beta/Applications/Xcode-27.0.0-Beta.6.app), booted into macOS 26.6.2.
sudo xcode-select -s /Applications/Xcode-26.6.0.app/Contents/Developer.
- Archive an app whose target has the standard Crashlytics
run / upload-symbols --build-phase script phase.
Expected: upload-symbols uses the selected Xcode (DEVELOPER_DIR / xcode-select -p) and uploads dSYMs.
Actual: it loads frameworks from the Xcode 27 beta, Gatekeeper blocks the load with the "damaged" modal, and the build phase blocks until a human dismisses it.
Evidence that upload-symbols is the process holding the beta Xcode open:
$ lsof +D "/Volumes/macOS Beta/Applications/Xcode-27.0.0-Beta.6.app"
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
upload-sy 21363 jmartin txt REG 1,30 776672 38894931 .../Xcode-27.0.0-Beta.6.app/Contents/SharedFrameworks/DebugSymbolsDT.framework/Versions/A/DebugSymbolsDT
upload-sy 21363 jmartin 5r REG 1,30 776672 38894931 .../Xcode-27.0.0-Beta.6.app/Contents/SharedFrameworks/DebugSymbolsDT.framework/Versions/A/DebugSymbolsDT
$ ps -o pid,ppid,command -p 21363
PID PPID COMMAND
21363 21362 .../firebase-ios-sdk/Crashlytics/upload-symbols --build-phase
# 21362 = /bin/sh .../firebase-ios-sdk/Crashlytics/run
The candidate list LaunchServices hands it, in order:
$ mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'"
/Volumes/macOS Beta/Users/jmartin/.Trash/Xcode-27.0.0-Beta.5.app
/Volumes/macOS Beta/Applications/Xcode-27.0.0-Beta.6.app
/Applications/Xcode-26.6.0.app # <- the selected one
$ xcode-select -p
/Applications/Xcode-26.6.0.app/Contents/Developer
And the versions it compares — the beta wins:
Xcode 27.0b6 CoreSymbolicationDT CFBundleVersion = 64578.87
Xcode 26.6 CoreSymbolicationDT CFBundleVersion = 64576.2
Background
I've got an external NVMe drive from which I boot macOS 27 + Xcode 27. On switching back to my macOS 26 boot partition, I started getting 5+ of these errors pop ups and need dismissing during each release builds:
The annoying part is it means that it requires user interaction in the GUI to unblock the build process.
This is expected behavior when Xcode 27 is attempted to be launched from macOS 26. However, I was running these builds with Xcode 26.6 selected. I set claude to track down the process that was spawning this Xcode invocation and gatekeeper error modal. This is what it came back with, which seems entirely plausible.
Description
Crashlytics/upload-symbolslocates Xcode by asking LaunchServices for every app registered with bundle identifiercom.apple.dt.Xcode, then picks the candidate with the highestCoreSymbolicationDT.frameworkbundle version anddlopensDebugSymbolsDT/CoreSymbolicationDTout of it. It ignores which Xcode is actually selected (xcode-select/ theDEVELOPER_DIRthat Xcode itself exports into the run-script build phase).This found the 27 Beta Xcode on the secondary boot volume, which makes
upload-symbolsload private frameworks from an Xcode that the running OS cannot use.Reproduction steps
/Applicationsand an Xcode 27 beta on another volume (/Volumes/macOS Beta/Applications/Xcode-27.0.0-Beta.6.app), booted into macOS 26.6.2.sudo xcode-select -s /Applications/Xcode-26.6.0.app/Contents/Developer.run/upload-symbols --build-phasescript phase.Expected:
upload-symbolsuses the selected Xcode (DEVELOPER_DIR/xcode-select -p) and uploads dSYMs.Actual: it loads frameworks from the Xcode 27 beta, Gatekeeper blocks the load with the "damaged" modal, and the build phase blocks until a human dismisses it.
Evidence that
upload-symbolsis the process holding the beta Xcode open:The candidate list LaunchServices hands it, in order:
And the versions it compares — the beta wins: