Fix MissingReferenceException when stopping scene with active mic#310
Merged
MaxHeimbrock merged 1 commit intoJun 15, 2026
Merged
Conversation
On play-mode exit, Unity tears down the DontDestroyOnLoad LiveKitSDK GameObject (backing the MonoBehaviourContext singleton) before MeetManager.OnDestroy() runs. MicrophoneSource.Stop() then calls RunCoroutine, which did _instance.StartCoroutine(...) on the destroyed instance and threw a MissingReferenceException. Guard RunCoroutine: when _instance has been destroyed (Unity's overloaded == reports it as null), drain the coroutine synchronously via a new DrainCoroutine helper and invoke onComplete, instead of touching the dead MonoBehaviour. This keeps cleanup side effects working and protects every caller, not just MicrophoneSource. Add an EditMode regression test that deterministically reproduces the failure mode by pointing _instance at a DestroyImmediate-d object and asserting RunCoroutine drains without throwing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cloudwebrtc
approved these changes
Jun 15, 2026
xianshijing-lk
approved these changes
Jun 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Stopping the scene with an active microphone source consistently throws:
On play-mode exit, Unity tears down the
DontDestroyOnLoadLiveKitSDKGameObject (backing theMonoBehaviourContextsingleton) beforeMeetManager.OnDestroy()runs.MicrophoneSource.Stop()then callsRunCoroutine, which did_instance.StartCoroutine(...)on the destroyed instance and threw.Fix
Guard
RunCoroutine: when_instancehas been destroyed (Unity's overloaded==reports it asnull), drain the coroutine synchronously via a newDrainCoroutinehelper and invokeonComplete, instead of touching the dead MonoBehaviour.DrainCoroutinerecurses into nested enumerators and skips time-based yields (meaningless during shutdown). This keeps cleanup side effects working and protects every caller —MicrophoneSourceis currently the only one, but the fix lives at the shared entry point rather than at the call site.Test
Added an EditMode regression test (
Tests/EditMode/MonoBehaviourContextTests.cs) that deterministically reproduces the failure mode: it points_instanceat aDestroyImmediate-d object and assertsRunCoroutinedrains without throwing and still runs the body +onComplete. The original singleton is saved/restored via reflection so other tests are unaffected.The exception fires synchronously from
StartCoroutineonce its host is destroyed, so the test reproduces the precondition deterministically without needing Unity's actual play-mode-exit teardown ordering. Against the pre-fix code it fails withMissingReferenceException; with the fix it passes.