MoveParticipant: should participants who join after a move receive the moved participant's tracks?

Hello community!

We are using MoveParticipant on LiveKit Cloud to route participants between rooms, and we have hit something we cannot explain.

After a move, the moved participant’s tracks only get auto-subscribed by people who were already in the destination room at the moment the move ran. Anyone arriving later, by another move or by a normal join, does get participantConnected and trackPublished for them, and the publication shows up with permissionStatus: 'allowed', but the subscription never completes. It sits at isDesired: true / isSubscribed: false. We left one like that for 13 minutes and nothing changed. An explicit setSubscribed(false) then setSubscribed(true) fixes it instantly.

We moved four participants into one room 5 seconds apart and got a very clean pattern: the first one moved sees all the others, the last one moved sees none of the other three. All four subscribe normally to someone who had joined that room the normal way, and a participant who joins afterwards sees none of the four. So it is not about how the subscriber arrived, only about whether they were in the room when the publisher’s move ran. For a group move of N that comes out to N(N-1)/2 broken pairs, which hurts us because our main use case is admitting a group from a waiting room into a session.

Has anyone run into this? Is this expected for MoveParticipant, or should a moved participant’s tracks be subscribable by people who arrive afterwards?

We have a workaround (the moved participant calls republishAllTracks() after the move, which routes the tracks through the normal publish path and fixes it completely). But we would rather understand the cause than ship around it.


Versions: livekit-client@2.20.1, livekit-server-sdk@2.17.0, server 1.13.3 (Cloud), Chrome 150, autoSubscribe and adaptiveStream both on.

Counting room events on the last-moved participant, in the destination room after its move:

 5  participantConnected
10  trackPublished
 4  trackSubscribed    <- only the two normally-joined participants

All ten publications are advertised, only the four from normal joiners are subscribed. In chrome://webrtc-internals the server’s answer after the move carries the normal joiner’s two tracks and nothing else, with six m-lines sitting inactive with no msid and no ssrc, so it was not short of slots. Two more answers follow before we intervene and neither carries the moved participants’ tracks. When we finally toggle setSubscribed, the server fills one of those idle m-lines on the first request, in the same negotiation cycle, no error.

One detail that surprised us: the track SID does not change across the move. The last-moved participant had been subscribed to that exact camera SID back in the source room, and after both were moved it is the same SID, now unsubscribable.

Ruled out: adaptiveStream (audio fails identically and is not visibility-gated, and isDesired is true throughout), permissions (allowed on every stuck publication), a reconnect (ICE ufrag unchanged all session, ICE connected once and never again), transceiver exhaustion (six idle m-lines), a stalled renegotiation (16 offer/answer cycles, all reaching stable), and a race (the pattern is exact and repeatable across sessions and two different Cloud nodes).

This is not something specific to our app. We reproduced the same behaviour using LiveKit’s own examples: Meet as the client, and realtime-room-monitor to trigger the moves, which we forked to add a MoveParticipant action since it does not ship with one. Same result: the moved participants show up in the grid, but their tiles stay black for anyone who was not already in the room when the move ran.

Thanks for any pointers.

Thank you for the detailed report. I’ve spent sometime looking at this and believe it may be an issue on the server. I am passing this on to our server team for deeper review as it is a bit outside my expertise.

I will report back when I have some more information.

Your work around looks like a safe path forward for now.

Thank you so much @CWilson !

We believe we have isolated the issue on this. Can you please test again and let me know if you have any further issues?

@CWilson the issue seems to be fixed: in our tests there is no need to republish the tracks after the move anymore. I will let you know if there are other issues, but the issue I’ve reported seems to be corrected now.

Thank you so much!