Skip to content

Multiple Runtime Issues with swift-subprocess on macOS 26 / Swift 6.2 #192

@oscarvarto

Description

@oscarvarto

Multiple Runtime Issues with swift-subprocess on macOS 26 / Swift 6.2

Summary

Swift projects using swift-subprocess encounter two distinct runtime issues on macOS 26 with Swift 6.2:

  1. Debug builds: Fail at runtime with dyld error about missing libswiftCompatibilitySpan.dylib
  2. Release builds: Hang indefinitely during subprocess execution (even after fixing the dyld issue)

These issues occur with both the latest main branch and the stable 0.1.0 release of swift-subprocess.

Environment

  • macOS: Tahoe 26 (Apple Silicon)
  • Swift Version: 6.2 (multiple toolchains tested)
    • Swiftly-provided: Apple Swift version 6.2 (swift-6.2-RELEASE)
    • Xcode-provided: Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)
  • Xcode: 26.0.1
  • Package Manager: Swift Package Manager 6.0
  • Target Platform: macOS 13.0+

Error Details

Issue 1: Debug Build Runtime Error (SOLVED)

dyld[PID]: Library not loaded: @rpath/libswiftCompatibilitySpan.dylib
  Referenced from: <UUID> /path/to/project/.build/arm64-apple-macosx/debug/ExecutableName
  Reason: tried: '/path/to/project/.build/arm64-apple-macosx/debug/libswiftCompatibilitySpan.dylib' (no such file),
           '/path/to/project/.build/arm64-apple-macosx/debug/libswiftCompatibilitySpan.dylib' (no such file),
           '/usr/local/lib/libswiftCompatibilitySpan.dylib' (no such file),
           '/usr/lib/libswiftCompatibilitySpan.dylib' (no such file, not in dyld cache)

Status: ✅ SOLVED - Fixed by setting Swift tools version to 6.2 and platform target to macOS(.v26)

Issue 2: Release Build Infinite Hang (UNSOLVED)

After fixing the dyld issue, release builds (swift build -c release) hang indefinitely when executing subprocess commands. The executable never completes and must be force-killed.

Status: ❌ BLOCKING - This prevents deployment of release binaries

Build Behavior

  • Compilation: Both debug and release builds compile successfully without errors
  • Debug runtime: Works correctly after applying the platform target fix
  • Release runtime: Hangs indefinitely during subprocess execution

Reproduction Steps

For Issue 1 (dyld error with debug builds):

  1. Create a new Swift package with Swift tools version 6.0 and platform macOS(.v13)
  2. Add swift-subprocess as a dependency (either main branch or 0.1.0 release)
  3. Create a simple executable that uses Subprocess:
import Subprocess

@main
struct TestApp {
    static func main() async throws {
        let result = try await Subprocess.run(.name("echo"), arguments: ["hello"])
        print(result.standardOutput ?? "")
    }
}
  1. Build and run: swift run TestApp

Expected: Program runs and prints "hello"
Actual: Runtime error about missing libswiftCompatibilitySpan.dylib

For Issue 2 (release build hang):

  1. Apply the fix for Issue 1: Set Swift tools version to 6.2 and platform to macOS(.v26)
  2. Build in release mode: swift build -c release
  3. Run the release binary: ./.build/release/TestApp

Expected: Program runs and prints "hello"
Actual: Program hangs indefinitely and never completes

Investigation

Package.swift Configurations Tested

Configuration causing Issue 1 (dyld error):

// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "TestProject",
    platforms: [.macOS(.v13)], // ❌ Causes dyld error
    dependencies: [
        .package(url: "https://github.com/swiftlang/swift-subprocess.git", branch: "main")
    ],
    targets: [
        .executableTarget(
            name: "TestApp",
            dependencies: [
                .product(name: "Subprocess", package: "swift-subprocess")
            ]
        )
    ]
)

Configuration that fixes Issue 1 but causes Issue 2:

// swift-tools-version: 6.2  // ✅ Required for macOS(.v26)
import PackageDescription

let package = Package(
    name: "TestProject",
    platforms: [.macOS(.v26)], // ✅ Fixes dyld, ❌ causes release hang
    dependencies: [
        .package(url: "https://github.com/swiftlang/swift-subprocess.git", branch: "main")
    ],
    targets: [
        .executableTarget(
            name: "TestApp",
            dependencies: [
                .product(name: "Subprocess", package: "swift-subprocess")
            ]
        )
    ]
)

Attempted Workarounds

For Issue 1 (dyld error):

  1. Different Swift toolchains: Tested both swiftly-managed and Xcode-provided Swift 6.2 toolchains - ❌ No effect
  2. Package versions: Tested both main branch and 0.1.0 stable release - ❌ No effect
  3. Custom defines: Attempted to disable Span with DISABLE_SUBPROCESS_SPAN compiler flag - ❌ No effect
  4. Package traits: Attempted to specify traits (not available in SPM 6.0) - ❌ Not supported
  5. Platform target update: Changed from macOS(.v13) to macOS(.v26) - ✅ SOLVED Issue 1

For Issue 2 (release hang):

  1. Different subprocess commands: Tested with echo, ls, tar - ❌ All hang
  2. Timeout configurations: Added custom timeouts to subprocess calls - ❌ Still hangs
  3. Different output configurations: Tested .string(), .data(), .discarded - ❌ Still hangs

No workaround found for Issue 2 - Release builds remain unusable.

Analysis

Issue 1 Analysis (SOLVED)

The dyld error occurs because swift-subprocess tries to use Swift 6.2's new Span APIs through a compatibility library (libswiftCompatibilitySpan.dylib) when targeting older macOS versions. This was fixed in Swift Package Manager PR #9164, which adds proper rpaths for the span compatibility library when targeting macOS < 26.

Root cause: Platform target mismatch between Swift 6.2 toolchain and older macOS target
Solution: Use macOS(.v26) platform target with Swift tools version 6.2

Issue 2 Analysis (UNSOLVED)

The release build hanging issue is exactly the same as described in swift-subprocess issue #182. Debug builds work correctly, but release builds hang indefinitely during subprocess execution.

Root cause: Unknown optimization-related issue in release builds
Impact: Prevents production deployment of applications using swift-subprocess

Span Trait Behavior

Based on the swift-subprocess documentation, the package offers two traits:

  • SubprocessFoundation: Default, includes Foundation dependency
  • SubprocessSpan: Uses RawSpan-based APIs, enabled automatically when RawSpan is available

The library automatically enables SubprocessSpan on Swift 6.2, which triggers both issues.

Expected Behavior

  1. For Issue 1 (dyld error):

    • RESOLVED - Developers should use macOS(.v26) platform target with Swift 6.2
    • Documentation should clearly state this requirement
  2. For Issue 2 (release hang):

    • Release builds should work as reliably as debug builds
    • Subprocess execution should complete successfully in all build configurations
    • The package should provide guidance on release build compatibility
  3. General expectations:

    • Clear documentation about Swift 6.2 and macOS 26 requirements
    • Explicit configuration options to disable Span support if needed
    • Reliable behavior across debug and release builds

Current Status & Workarounds

Issue 1 (dyld error): ✅ SOLVED

Workaround: Update Package.swift to use Swift tools version 6.2 and platform target macOS(.v26)

Issue 2 (release hang): ❌ BLOCKING

No viable workaround - Options are:

  1. Use only debug builds (not suitable for production)
  2. Implement subprocess functionality using Foundation's Process class
  3. Wait for a fix to issue Swift Subprocess hangs in release builds but works in debug builds #182

Related Issues

Additional Context

Issue 2 (release hang) blocks production deployment of swift-subprocess applications. While Issue 1 has been resolved, the release build hanging problem makes the library unsuitable for production use on macOS 26 with Swift 6.2.

This appears to be an optimization-related bug where release builds hang during subprocess execution, while debug builds work correctly. The issue affects all subprocess operations regardless of the command being executed or output configuration.

Immediate impact: Developers using swift-subprocess must either:

  • Ship debug builds (poor performance, not production-ready)
  • Switch to Foundation's Process class
  • Delay deployment until the hanging issue is resolved

The automatic Span trait detection in Swift 6.2 environments may be contributing to both issues, suggesting the need for more explicit trait configuration options.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions