Skip to content

Room.disconnect delivers TerminatedException to active text stream collectors #964

@weefbellington

Description

@weefbellington

Describe the bug

When Room.disconnect() is called while incoming text streams are open, every open stream channel is closed with an exception cause (IncomingDataStreamManagerImpl.clearOpenStreams):

descriptor.channel.close(StreamException.TerminatedException())

Because TextStreamReceiver.flow is channel.receiveAsFlow(), that exception is rethrown into whatever coroutine is collecting the receiver's flow. In our app the collectors run in a session-scoped coroutine, so a clean, client-initiated disconnect tears down the scope as an uncaught exception:

Session scope canceled with error: UnknownError(cause=StreamException$TerminatedException)

If a stream's header has arrived but its trailer has not yet been received at disconnect time (typical for in-progress transcription segments), this fires on every normal hang-up.

Steps to reproduce

  1. room.registerTextStreamHandler(topic) { receiver, _ -> scope.launch { receiver.flow.collect { ... } } }
  2. Have the remote participant publish to the topic continuously (e.g. live transcription).
  3. Call room.disconnect() while a stream is open.
  4. The collector throws StreamException.TerminatedException.

Expected behavior

One of:

  • A clean client-initiated disconnect closes stream channels without a cause (the same way handleStreamTrailer closes channels on normal completion), so collectors complete normally; or
  • The current behavior is the intended contract, and it's documented. Neither the text streams guide nor the API reference for TerminatedException ("Stream terminated before completion") currently says collectors will receive this on room disconnect.

Possibly related: #881 is the same pattern with StreamException$IncompleteException — stream-channel close causes escaping into consumer coroutines as fatal exceptions. A documented contract for stream error delivery would cover both.

Device Info:

  • LiveKit SDK version: 2.25.3 (behavior unchanged on main as of 2026-06-10)
  • Observed on: Pixel device, Android 16

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions