Hive Hive
Sign in

SwifterPM: cold-cache registry install fails to load manifest because the registry-host path segment is omitted

GitHub issue · Open

Metadata
Source
tuist/tuist #15037
Updated
Oct 30, 2026
Details

What happened?

With Tuist 4.214.0 and Xcode 27.2, tuist install fails for a registry dependency when TUIST_USE_SWIFTERPM=true, even in a newly created project with independently empty cache directories. The same minimal project succeeds with TUIST_USE_SWIFTERPM=false and another independently empty set of caches.

The sample has a single public dependency:

.package(id: "CombineCommunity.CombineExt", exact: "1.9.0")

The downloaded manifest exists at:

Tuist/.build/registry/downloads/tuist.dev-312510bf/CombineCommunity/CombineExt/1.9.0/Package.swift

Tuist/.build/workspace-state.json also records the registry dependency’s subpath as:

tuist.dev-312510bf/CombineCommunity/CombineExt/1.9.0

However, the failing manifest load uses:

Tuist/.build/registry/downloads/CombineCommunity/CombineExt/1.9.0

The registry-host directory segment is missing from the attempted path.

Expected: installation succeeds and loads the manifest from the actual downloaded location, as the native SwiftPM control does.

How do we reproduce it?

Minimal project generator, failing log, successful control log, and environment details.

The attached reproduce.py uses only Python’s standard library. It creates the complete minimal Tuist project on each invocation, asserts that both the project scratch directory and dependency cache do not exist before installation, and retains the generated project, logs, and result JSON for inspection. It requires no private dependencies, application source, or credentials.

  1. Use Tuist 4.214.0 and Xcode 27.2.
  2. Download reproduce.py from the linked sample.
  3. Run with the absolute path to the Tuist executable:
TUIST_EXECUTABLE="$(mise which tuist)"
python3 reproduce.py "$TUIST_EXECUTABLE" true
python3 reproduce.py "$TUIST_EXECUTABLE" false

For installations without mise, pass the absolute path to the Tuist 4.214.0 executable directly.

Each command creates a separate new project and separate new caches. Results:

Mode Initial project/cache state Exit code
TUIST_USE_SWIFTERPM=true Empty 1
TUIST_USE_SWIFTERPM=false Independently empty 0

Cache isolation is configured using:

  • installOptions: .options(passthroughSwiftPackageManagerArguments: [...]) with explicit --cache-path, --config-path, and --security-path paths inside the new run directory.
  • XDG_CACHE_HOME inside that same run directory, isolating the default SwifterPM/Tuist caches.
  • CLANG_MODULE_CACHE_PATH and SWIFTPM_MODULECACHE_OVERRIDE inside the run directory.
  • A newly created Tuist/.swiftpm/configuration/registries.json pointing to https://tuist.dev/api/registry/swift.

The existing user caches are neither removed nor used as the configured dependency-cache locations. The failing sample’s generated tree contains no symlinks to external caches. No Package.resolved or .build directory is copied into the minimal sample.

Error log

Resolving and fetching plugins.
Resolving and fetching dependencies.
Computing version for CombineCommunity.CombineExt
Computed CombineCommunity.CombineExt at 1.9.0 (0.81s)
Fetching CombineCommunity.CombineExt
[81269/217363] Fetching CombineCommunity.CombineExt
Fetched CombineCommunity.CombineExt from cache (0.52s)
✖ Error
failed to load the manifest for CombineCommunity.CombineExt: could not read <RUN_ROOT>/project/Tuist/.build/registry/downloads/CombineCommunity/CombineExt/1.9.0: Failed to set working directory to "<RUN_ROOT>/project/Tuist/.build/registry/downloads/CombineCommunity/CombineExt/1.9.0".

The log’s “from cache” message occurs within this single installation after starting with an absent explicitly configured dependency-cache directory. Both complete logs and the recorded actual manifest paths are included in the sample.

macOS version

27.2 (arm64)

Tuist version

4.214.0

Xcode version

27.2 (27B52), Apple Swift 6.4.2 (swiftlang-6.4.2.1.9 clang-2100.4.1.1)

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments