Skip to content

Build-tool plugin breaks swift-collections module resolution during xcodebuild archive #890

@EdmundKorley

Description

@EdmundKorley

Description

When archiving an iOS project that uses swift-openapi-generator as a build-tool plugin, xcodebuild archive fails with:

swift-collections/Sources/ContainersPreview/Extensions/OutputSpan+Extras.swift:17:8: 
error: Unable to find module dependency: 'InternalCollectionsUtilities'

The same project builds and archives successfully when the OpenAPI generator plugin is removed from Package.swift and the generated sources (Types.swift, Client.swift) are committed directly.

Environment

  • Xcode 26.2 (Swift 6.2.3) and Xcode 26.4 (Swift 6.3)
  • swift-openapi-generator 1.10.4
  • swift-openapi-runtime 1.11.0
  • swift-collections 1.4.0 (transitive dependency via openapi-runtime)
  • macOS 26 (Tahoe), both local and GitHub Actions CI (macos-26 runner)
  • SWIFT_ENABLE_EXPLICIT_MODULES=NO does not resolve the issue

Reproduction

  1. Create an Xcode project with a local SPM package that uses OpenAPIGenerator as a build plugin
  2. The package depends on swift-openapi-runtime which transitively pulls swift-collections 1.4.0
  3. Run: xcodebuild archive -scheme <Scheme> -sdk iphoneos -configuration Release -derivedDataPath /tmp/clean-dd -skipPackagePluginValidation
  4. Archive fails with the InternalCollectionsUtilities module not found error

Key observation: The error does NOT occur when:

  • Building for simulator (-sdk iphonesimulator)
  • Building Debug configuration
  • The plugin is removed and generated sources are committed directly
  • Using incremental builds with cached DerivedData

It ONLY fails with a clean DerivedData + archive + iphoneos SDK, suggesting the plugin's execution interferes with SPM's build graph ordering for device archives.

Workaround

Pre-generate the OpenAPI sources using the CLI tool, then strip the plugin from Package.swift before archiving:

# 1. Resolve packages
xcodebuild -resolvePackageDependencies -scheme MyApp -derivedDataPath /tmp/bootstrap

# 2. Generate sources via CLI
swift run --package-path /tmp/bootstrap/SourcePackages/checkouts/swift-openapi-generator   swift-openapi-generator generate openapi.json   --config openapi-generator-config.yaml   --output-directory Sources/MyOpenAPIClient/   --plugin-source build

# 3. Strip plugin from Package.swift
# Remove .package(url: "swift-openapi-generator", ...) and plugins: [...] 

# 4. Archive without plugin
xcodebuild archive -scheme MyApp -sdk iphoneos ...

This is what we use in CI, but it adds significant complexity to the workflow.

Related issues

Expected behavior

xcodebuild archive should succeed with the OpenAPI generator build-tool plugin present, same as it does for Debug/Simulator builds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions