Skip to content

Build fails with "circular reference" on Xcode 26.4.0 Beta due to indirect enum in ConnectionStatus.swift #3972

@gtsifrikas

Description

@gtsifrikas

Describe the bug

Building StreamChat with Xcode 26.4.0 Beta fails with circular reference compiler errors originating from ConnectionStatus.swift. The issue is caused by the indirect enum DisconnectionSource nested inside WebSocketConnectionState, where the timeout(from: WebSocketConnectionState) case references the parent enum.

This is a Swift compiler regression in the Xcode 26.4.0 Beta toolchain (specifically in the explicit module / compilation caching build path). The same code compiles successfully on Xcode 26.3 and via swift build (SPM CLI).

To Reproduce

  1. Add stream-chat-swift (any recent version, e.g. 4.97.1) as a dependency
  2. Build using Xcode 26.4.0 Beta (build system, not SPM CLI)
  3. Observe errors:
<unknown>:0: error: circular reference
ConnectionStatus.swift:56:19: note: through reference here
    indirect enum DisconnectionSource: Equatable {
                  ^
ConnectionStatus.swift:54:6: note: through reference here
enum WebSocketConnectionState: Equatable {
     ^

Every file in the StreamChat module fails with this error since it's a module-level compilation failure.

Expected behavior

The code should compile. indirect enum is specifically designed to handle recursive/circular type references, and this pattern compiles on Xcode 26.3 and earlier.

Environment

  • Xcode: 26.4.0 Beta
  • Working Xcode: 26.3 (stable)
  • macOS: Darwin 25.4.0
  • StreamChat version: 4.97.1 (also reproducible on earlier versions)
  • Build method: Xcode build system (xcodebuild or Xcode IDE) — swift build CLI works fine

Root cause

The bug is in the Xcode 26.4.0 Beta Swift compiler's explicit module build path (-disable-implicit-swift-modules, -cache-compile-job, -cas-path). I've filed a Feedback with Apple.

Affected code

Sources/StreamChat/WebSocketClient/ConnectionStatus.swift lines 54-61:

enum WebSocketConnectionState: Equatable {
    indirect enum DisconnectionSource: Equatable {
        case userInitiated
        case timeout(from: WebSocketConnectionState) // ← references parent
        case serverInitiated(error: ClientError? = nil)
        case systemInitiated
        case noPongReceived
    }
    // ...
}

Possible workaround

One potential workaround (if you want to support Xcode 26.4 beta users) would be to move DisconnectionSource out of WebSocketConnectionState as a sibling type, removing the nesting. This may avoid triggering the compiler bug while preserving the same semantics. However, since this is an Apple compiler bug, it may be preferable to wait for a fix from Apple.

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