Skip to content

Memory leak: constructor event listeners not removed on room destruction #1940

@basslagter

Description

@basslagter

Describe the bug

Event listeners registered in the Room constructor (e.g. devicechange on navigator.mediaDevices) are never removed unless handleDisconnect is called. When a Room instance is destroyed before a disconnect event fires — for example during component unmount, route change, or explicit cleanup — the listener remains attached to the global navigator.mediaDevices object.

This causes a memory leak and can trigger callbacks on a dead room instance, leading to unexpected side effects or errors in long-lived applications that create and destroy multiple room instances.

Reproduction

  1. Create a Room instance and connect it to a LiveKit server.
  2. Destroy or discard the Room instance without calling disconnect() — e.g. replace the reference, unmount the component, or navigate away.
  3. Inspect navigator.mediaDevices event listeners (e.g. via browser DevTools or a test spy).
  4. Observe that the devicechange listener from the destroyed room is still registered.

Logs

System Info

https://github.com/livekit/client-sdk-js
Tested on Chrome, macOS.

Severity

serious, but I can work around it

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions