Describe the bug
What I'm expecting
Joining and leaving an audio-only room (<LiveKitRoom video={false} audio={true} ...>) should not log console.error lines when no actual error has occurred.
What happens instead
On every room leave / route change, Unknown DataChannel error on lossy and/or Unknown DataChannel error on reliable is logged at error severity. The underlying browser event is a generic Event (not ErrorEvent) emitted during graceful close / ICE restart cleanup — event.message and event.error are undefined. There is no actual failure; audio works correctly. But the red console.error lines:
- Get flagged by error-tracking tools (Sentry / Datadog RUM) as production errors
- Confuse developers reviewing console output
- Have no diagnostic value (payload
{ event } contains no usable information)
Code location
src/room/RTCEngine.ts:996-1006:
private handleDataError = (event: Event) => {
const channel = event.currentTarget as RTCDataChannel;
const channelKind = channel.maxRetransmits === 0 ? 'lossy' : 'reliable';
if (event instanceof ErrorEvent && event.error) {
const { error } = event.error;
this.log.error(`DataChannel error on ${channelKind}: ${event.message}`, { error });
} else {
this.log.error(`Unknown DataChannel error on ${channelKind}`, { event }); // ← issue
}
};
The else branch fires when event is NOT an ErrorEvent with event.error populated — i.e. there is no actual error data, yet it is logged at error severity.
Proposed fix
Downgrade else branch from log.error to log.debug (one-line diff):
} else {
- this.log.error(`Unknown DataChannel error on ${channelKind}`, { event });
+ this.log.debug(`Unknown DataChannel error on ${channelKind}`, { event });
}
Rationale:
- Real errors (with
event.error populated) still take the if branch — unaffected
log.debug is invisible by default but available via setLogLevel('debug') for users actively debugging data channels
- Zero behavioral change — only severity adjustment of an informational log
Reproduction
- Create a minimal audio-only room with
livekit-client 2.19.0:
import { Room } from 'livekit-client';
const room = new Room();
await room.connect(serverUrl, token);
await room.localParticipant.setMicrophoneEnabled(true);
// ... use room for a bit ...
await room.disconnect();
Or, equivalently, using @livekit/components-react:
<LiveKitRoom token={token} serverUrl={url} video={false} audio={true} connect>
<RoomAudioRenderer />
</LiveKitRoom>
- Trigger a leave (
room.disconnect(), route change, or component unmount).
- Observe DevTools Console — red
Unknown DataChannel error on lossy / Unknown DataChannel error on reliable lines appear.
Reproduces consistently across Chrome 130 / Firefox 132 / Safari 18 (tested) on every leave.
Logs
Unknown DataChannel error on lossy
at HTMLDocument.<anonymous> (livekit-client.esm.mjs:21183)
...
Unknown DataChannel error on reliable
at HTMLDocument.<anonymous> (livekit-client.esm.mjs:21183)
...
Payload object (when inspected): { event: Event { isTrusted: true, type: 'error', target: RTCDataChannel } } — no message, no error, no stack beyond the SDK's own log call site.
System Info
System:
OS: macOS 12.6.3
CPU: (4) x64 Intel(R) Core(TM) i5-5250U CPU @ 1.60GHz
Memory: 40.92 MB / 4.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 24.15.0 - /usr/local/bin/node
npm: 11.12.1 - /usr/local/bin/npm
Browsers:
Brave Browser: 110.1.48.171
Safari: 17.6
npmPackages:
@livekit/components-react: ^2.9.21 => 2.9.21
livekit-client: ^2.19.0 => 2.19.0
livekit-server-sdk: ^2.15.3 => 2.15.3
Also reproduced on Chrome 130 and Firefox 132 (separate test machine).
Severity
annoyance
Additional Information
Workarounds attempted (none satisfactory)
setLogExtension (Sentry-style log forwarding) — only forwards logs downstream, does not filter or suppress upstream console.error.
setLogLevel('warn') on the engine logger — silences all errors, too broad.
RoomOptions.logger / custom logger injection — not in stable public API.
- Avoid creating data channels when
video: false — RTCEngine.createDataChannels() (line 827) is called unconditionally regardless of published media tracks.
- Override
console.error globally — works but global side effect, fragile, breaks other error tooling.
patch-package with the proposed one-line diff — current workaround in our project (Next.js 16 + React 19, audio-only tutoring app); applied at build time via postinstall.
Willing to submit PR
Yes — happy to open a PR with the one-line diff above if maintainers agree on the approach. Open to alternative approaches (e.g. add an option to silence specific log categories) if preferred.
Describe the bug
What I'm expecting
Joining and leaving an audio-only room (
<LiveKitRoom video={false} audio={true} ...>) should not logconsole.errorlines when no actual error has occurred.What happens instead
On every room leave / route change,
Unknown DataChannel error on lossyand/orUnknown DataChannel error on reliableis logged aterrorseverity. The underlying browser event is a genericEvent(notErrorEvent) emitted during graceful close / ICE restart cleanup —event.messageandevent.errorareundefined. There is no actual failure; audio works correctly. But the redconsole.errorlines:{ event }contains no usable information)Code location
src/room/RTCEngine.ts:996-1006:The
elsebranch fires wheneventis NOT anErrorEventwithevent.errorpopulated — i.e. there is no actual error data, yet it is logged aterrorseverity.Proposed fix
Downgrade
elsebranch fromlog.errortolog.debug(one-line diff):} else { - this.log.error(`Unknown DataChannel error on ${channelKind}`, { event }); + this.log.debug(`Unknown DataChannel error on ${channelKind}`, { event }); }Rationale:
event.errorpopulated) still take theifbranch — unaffectedlog.debugis invisible by default but available viasetLogLevel('debug')for users actively debugging data channelsReproduction
livekit-client2.19.0:Or, equivalently, using
@livekit/components-react:room.disconnect(), route change, or component unmount).Unknown DataChannel error on lossy/Unknown DataChannel error on reliablelines appear.Reproduces consistently across Chrome 130 / Firefox 132 / Safari 18 (tested) on every leave.
Logs
Payload object (when inspected):
{ event: Event { isTrusted: true, type: 'error', target: RTCDataChannel } }— nomessage, noerror, nostackbeyond the SDK's own log call site.System Info
System: OS: macOS 12.6.3 CPU: (4) x64 Intel(R) Core(TM) i5-5250U CPU @ 1.60GHz Memory: 40.92 MB / 4.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 24.15.0 - /usr/local/bin/node npm: 11.12.1 - /usr/local/bin/npm Browsers: Brave Browser: 110.1.48.171 Safari: 17.6 npmPackages: @livekit/components-react: ^2.9.21 => 2.9.21 livekit-client: ^2.19.0 => 2.19.0 livekit-server-sdk: ^2.15.3 => 2.15.3Also reproduced on Chrome 130 and Firefox 132 (separate test machine).
Severity
annoyance
Additional Information
Workarounds attempted (none satisfactory)
setLogExtension(Sentry-style log forwarding) — only forwards logs downstream, does not filter or suppress upstreamconsole.error.setLogLevel('warn')on the engine logger — silences all errors, too broad.RoomOptions.logger/ custom logger injection — not in stable public API.video: false—RTCEngine.createDataChannels()(line 827) is called unconditionally regardless of published media tracks.console.errorglobally — works but global side effect, fragile, breaks other error tooling.patch-packagewith the proposed one-line diff — current workaround in our project (Next.js 16 + React 19, audio-only tutoring app); applied at build time viapostinstall.Willing to submit PR
Yes — happy to open a PR with the one-line diff above if maintainers agree on the approach. Open to alternative approaches (e.g. add an option to silence specific log categories) if preferred.