fix(iOS): prevent UUID collision corrupting Pods project in spm_dependency#57576
Closed
chrfalch wants to merge 1 commit into
Closed
fix(iOS): prevent UUID collision corrupting Pods project in spm_dependency#57576chrfalch wants to merge 1 commit into
chrfalch wants to merge 1 commit into
Conversation
…dency spm_dependency injects XCRemoteSwiftPackageReference / XCSwiftPackageProductDependency objects into the Pods project from a post_install hook via project.new(...). CocoaPods' Pod::Project overrides UUID generation with a deterministic counter scheme (prefix + %07X counter + trailing 0) and deliberately skips collision checks, assuming the project is always freshly generated. When the generator counters are out of sync with the loaded object graph, the first generated UUID can collide with an existing object — in the observed failure, the root PBXProject's own UUID (46EB2E00000000). The injected package reference then silently overwrites the root object entry, and the saved pbxproj's rootObject points at the package reference. Xcode fails to load the project: -[XCRemoteSwiftPackageReference _setSavedArchiveVersion:]: unrecognized selector "The project 'Pods' is damaged and cannot be opened." This broke the react-native-enriched-markdown job in nightly-tests on 0.88.0-nightly-20260716 after the Pods graph grew with the prebuilt pods; the bug itself is latent and independent of that change. Fix: route object creation through a new_object helper that keeps the deterministic counter scheme but probes generate_uuid forward past any UUID already present in objects_by_uuid. Uniqueness is guaranteed against the live object table regardless of project size or state, and repeated pod installs remain stable via the existing find-before-create dedup guards. Adds a standalone test (scripts/cocoapods/__tests__/spm-test.rb) covering fresh-project injection, the reload/collision regression, and global UUID uniqueness. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this in D112320831. |
|
@cipolleschi merged this pull request in 1cdf784. |
react-native-bot
pushed a commit
that referenced
this pull request
Jul 16, 2026
…dency (#57576) Summary: The first nightly containing the prebuilt/SwiftPM stack (`0.88.0-nightly-20260716`) broke the `react-native-enriched-markdown` job in [react-native-community/nightly-tests](https://github.com/react-native-community/nightly-tests/actions/runs/29476835418/job/87551590732): `pod install` succeeds, but xcodebuild cannot load the generated project: ``` -[XCRemoteSwiftPackageReference _setSavedArchiveVersion:]: unrecognized selector sent to instance Failed to load container at path: .../Pods/Pods.xcodeproj — "The project 'Pods' is damaged and cannot be opened." ``` **Root cause:** `spm_dependency` injects `XCRemoteSwiftPackageReference` / `XCSwiftPackageProductDependency` objects from a `post_install` hook via `project.new(...)`. CocoaPods' `Pod::Project` overrides UUID generation with a deterministic counter scheme (`prefix + %07X counter + trailing 0`) and deliberately skips collision checks, assuming the project is always freshly generated. When the generator counters are out of sync with the loaded object graph, the first generated UUID collides with an existing object — in the observed failure the root `PBXProject`'s own UUID (`46EB2E00000000`). The injected package reference silently overwrites the root object entry in `objects_by_uuid`, so the saved pbxproj's `rootObject` points at the package reference, and Xcode's loader sends `PBXProject`-only messages to it. The bug is latent in `spm_dependency` since its introduction; the recently grown Pods object graph merely exposed it. **Fix:** route object creation through a `new_object` helper that keeps the deterministic counter scheme but probes `generate_uuid` forward past any UUID already present in `objects_by_uuid`. Uniqueness is guaranteed against the live object table regardless of project size/state; `generate_uuid`'s counter is strictly monotonic, so the probe terminates and never repeats within a run. Repeated `pod install`s stay idempotent via the existing find-before-create dedup guards. ## Changelog: [IOS] [FIXED] - Fix "The project 'Pods' is damaged and cannot be opened" when a library uses `spm_dependency` and the generated UUID collides with an existing Pods project object Pull Request resolved: #57576 Test Plan: - New standalone test `scripts/cocoapods/__tests__/spm-test.rb` (runs via `ruby scripts/cocoapods/__tests__/spm-test.rb`, uses the real `Pod::Project`): - fresh-project injection (passes before and after — fresh counters don't collide, isolating the trigger), - injection after counter reset (reproduces the corruption against the previous code as `NoMethodError: undefined method 'product_ref_group' for ... XCRemoteSwiftPackageReference` on reload — the Ruby analog of Xcode's crash; passes with the fix), - global UUID uniqueness + clean `Xcodeproj::Project.open` round-trip. - 3 tests, 10 assertions, 0 failures with the fix. - E2E: to be confirmed with a `spm_dependency` library (e.g. react-native-enriched-markdown) in prebuilt mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: fabriziocucci Differential Revision: D112320831 Pulled By: cipolleschi fbshipit-source-id: de190f6492abff2cc6dbd94347e5346d11b50a41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
The first nightly containing the prebuilt/SwiftPM stack (
0.88.0-nightly-20260716) broke thereact-native-enriched-markdownjob in react-native-community/nightly-tests:pod installsucceeds, but xcodebuild cannot load the generated project:Root cause:
spm_dependencyinjectsXCRemoteSwiftPackageReference/XCSwiftPackageProductDependencyobjects from apost_installhook viaproject.new(...). CocoaPods'Pod::Projectoverrides UUID generation with a deterministic counter scheme (prefix + %07X counter + trailing 0) and deliberately skips collision checks, assuming the project is always freshly generated. When the generator counters are out of sync with the loaded object graph, the first generated UUID collides with an existing object — in the observed failure the rootPBXProject's own UUID (46EB2E00000000). The injected package reference silently overwrites the root object entry inobjects_by_uuid, so the saved pbxproj'srootObjectpoints at the package reference, and Xcode's loader sendsPBXProject-only messages to it. The bug is latent inspm_dependencysince its introduction; the recently grown Pods object graph merely exposed it.Fix: route object creation through a
new_objecthelper that keeps the deterministic counter scheme but probesgenerate_uuidforward past any UUID already present inobjects_by_uuid. Uniqueness is guaranteed against the live object table regardless of project size/state;generate_uuid's counter is strictly monotonic, so the probe terminates and never repeats within a run. Repeatedpod installs stay idempotent via the existing find-before-create dedup guards.Changelog:
[IOS] [FIXED] - Fix "The project 'Pods' is damaged and cannot be opened" when a library uses
spm_dependencyand the generated UUID collides with an existing Pods project objectTest Plan:
scripts/cocoapods/__tests__/spm-test.rb(runs viaruby scripts/cocoapods/__tests__/spm-test.rb, uses the realPod::Project):NoMethodError: undefined method 'product_ref_group' for ... XCRemoteSwiftPackageReferenceon reload — the Ruby analog of Xcode's crash; passes with the fix),Xcodeproj::Project.openround-trip.spm_dependencylibrary (e.g. react-native-enriched-markdown) in prebuilt mode.🤖 Generated with Claude Code