From 2e0b7f44b470498c956e7b16cc46807ce44fc102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82az=CC=87ej=20Pankowski?= <86720177+pblazej@users.noreply.github.com> Date: Tue, 14 Apr 2026 10:40:22 +0200 Subject: [PATCH] fix(transport): remove removeTrack loop before close to prevent crashes removeTrack nulls sender tracks and changes transceiver directions, causing PeerConnection::Close() to skip ClearSend/DetachTrack in its StopTransceiverProcedure and hit edge cases in the worker-thread teardown (ICE use-after-free, AVAudioEngine deallocation assertion). Close() handles full cleanup on its own. The loop was originally commented out as "not required?" and was accidentally uncommented during a threading refactor (101e09d0). Co-Authored-By: Claude Opus 4.6 (1M context) --- Sources/LiveKit/Core/Transport.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Sources/LiveKit/Core/Transport.swift b/Sources/LiveKit/Core/Transport.swift index e5ecff708..97f4bded0 100644 --- a/Sources/LiveKit/Core/Transport.swift +++ b/Sources/LiveKit/Core/Transport.swift @@ -204,11 +204,12 @@ actor Transport: NSObject, Loggable { // Stop listening to delegate _pc.delegate = nil - // Remove all senders (if any) - for sender in _pc.senders { - _pc.removeTrack(sender) - } + // Do not call removeTrack before close — it nulls sender tracks and + // changes transceiver directions, causing Close() to skip ClearSend/ + // DetachTrack in its StopTransceiverProcedure and hit edge cases in + // the worker-thread teardown (ICE use-after-free, AVAudioEngine + // deallocation assertion). Close() handles full cleanup on its own. _pc.close() } }