Skip to content

Retry a failed full reconnect instead of reporting it as success - #1144

Merged
pblazej merged 3 commits into
livekit:mainfrom
bgoepfert:fix/failed-full-reconnect-reads-connected
Oct 6, 2026
Merged

pblazej merged 3 commits into
livekit:mainfrom
bgoepfert:fix/failed-full-reconnect-reads-connected

Conversation

@bgoepfert

@bgoepfert bgoepfert commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

SDK version: 2.17.0 (also present on main)
Platform: macOS 15+ (logic is platform-independent)

Description

In Room+Engine.swift, startReconnect(reason:nextReconnectMode:), the retry closure passed to Task.retrying starts with:

// Full reconnect failed, give up
guard currentMode != .full else { return }

This returns normally instead of throwing. Task.retrying treats a normal return as success, so:

  1. A full reconnect attempt runs fullReconnectSequence(), which calls cleanUp(isFullReconnect: true) and then fails (for example, the signal connect or the transport connect times out). The closure rethrows, and Task.retrying waits and calls the closure again.
  2. On the next attempt isReconnectingWithMode is still .full, so the guard returns without doing anything.
  3. try await reconnectTask.value succeeds, and the code after it sets connectionState = .connected, clears reconnectTask and isReconnectingWithMode, and resets the region attempts.

The Room is now .connected, but its state was reset by cleanUp(isFullReconnect: true). Depending on where the full attempt failed, sid and remoteParticipants are empty, or the transports are not connected. No further reconnect is attempted, and didDisconnect never fires, so the app has no signal that the call is dead.

The same thing happens when the very first attempt is a full reconnect (for example, after a server Leave with action reconnect) and that attempt fails while attempts remain.

Expected

A failed full reconnect either retries the full reconnect on the remaining attempts, or ends in .disconnected with an error through the existing catch (cleanUp(withError:)), so that room(_:didDisconnectWithError:) fires.

Fix

Remove the guard. A later attempt now retries the full reconnect (the closure already picks .full while isReconnectingWithMode == .full), and when every attempt fails the existing catch runs cleanUp(withError:), so room(_:didDisconnectWithError:) fires.

Tests

FailedFullReconnectTests (E2E, local server):

  • everyFullAttemptFailingEndsDisconnected: every full attempt is rejected → the room ends .disconnected. On main it reads .connected.
  • aFullAttemptFailingOnceIsRetriedAndRecovers: the first full attempt fails, the next succeeds → the room is connected with a sid. On main it reads .connected with sid == nil.

The existing FullReconnectDataTests and RepublishTracksTests still pass.

Steps to reproduce

  1. Connect to a LiveKit Cloud room.
  2. Force a full reconnect (room.debug_simulate(scenario: .fullReconnect) or a server Leave with reconnect), and make the first full attempt fail, for example by blocking network access for about 15 s during the attempt.
  3. Restore the network. Observe connectionState == .connected, with room.sid == nil or empty remoteParticipants, no media, and no further reconnect or disconnect events.

Impact

Users see a "connected" call with no participants or media that never recovers until they leave and rejoin.

@CLAassistant

CLAassistant commented Oct 5, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Devin Review: 1 flag

Not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

@bgoepfert bgoepfert changed the title Failed full reconnect is reported as success: Room becomes .connected after cleanUp(isFullReconnect:) Retry a failed full reconnect instead of reporting it as success Oct 5, 2026
@bgoepfert

bgoepfert commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Hello 👋 This is the first time I've opened a PR to contribute to an open-source repo! I am using Livekit and this swift SDK quite heavily in a product I am building, and am keen to get involved when I can, so would be grateful for any general contributing feedback as well. Hopefully I have followed the process right here :)

@pblazej

pblazej commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Hey @bgoepfert I did a small update in the tests, thanks for fixing that 💯

There are some CI failures, mostly due to #1131 - I'd merge it first once approved.

@pblazej
pblazej merged commit d9b161b into livekit:main Oct 6, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants