Skip to content

Roll back the sender when publishing fails after AddTrack - #1102

Merged
pblazej merged 3 commits into
mainfrom
blaze/orphaned-track
Aug 28, 2026
Merged

Roll back the sender when publishing fails after AddTrack#1102
pblazej merged 3 commits into
mainfrom
blaze/orphaned-track

Conversation

@pblazej

@pblazej pblazej commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #1098

When _publish failed after AddTrack and negotiation had completed — deterministically on the audio frame-watcher timeout, but also on any negotiation failure after a successful AddTrack — the catch only called track.stop(). The sender stayed attached to the publisher PC and the server kept the publication, while the client had no LocalTrackPublication: mute was a no-op, isMicrophoneEnabled() lied, and a retry published a second track. Since capture was never stopped either, frames arriving after the timeout streamed live mic audio to the room.

There is no remove-track signal for media tracks; the SFU only learns about a removal through renegotiation. So the failure path now does what unpublish does: remove the sender from the publisher, renegotiate, and clear the track's transport/sender state. The backup-codec publish gets the same treatment, and unpublish now clears the track's sender so a later publish attempt on the same track starts clean.

Mirrors the fix Android shipped in livekit/client-sdk-android#986.

Test: a TestAudioTrack subclass that throws from startWaitingForFrames() (after letting negotiation reach the server) reproduces the exact failure point headlessly; the test asserts no local publication or sender remains, and that a retry leaves exactly one track visible to a remote participant. Without the rollback it fails with two tracks on the remote and the sender still attached.

Local server log for the test run, publisher side:

11:35:30.519  addTrack              cid 89A563FB…
11:35:30.551  mediaTrack published  TR_AMm3gsZsx5Kcjv   <- server holds a live publication
11:35:32.569  addTrack (retry)      cid 1F9B83F0…
11:35:32.777  track unpublished     TR_AMm3gsZsx5Kcjv   <- rollback renegotiation, ~200ms after the failure
11:35:32.778  mediaTrack published  TR_AMSsuoSJQtVn3Z
11:35:32.990  participant closing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pblazej
pblazej merged commit 6bb9e72 into main Aug 28, 2026
53 of 55 checks passed
@pblazej
pblazej deleted the blaze/orphaned-track branch August 28, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants