client-sdk-js
client-sdk-js copied to clipboard
Incorrect disconnection reason
Describe the bug
When LiveKit Cloud cannot reconnect to the server after several attempts, it gets an error in the disconnected handler with reason=DUPLICATE_IDENTITY.
Reproduction
There is information about incidents here: https://livekit-users.slack.com/archives/C048FRL1N2C/p1750258756078379
Logs
System Info
System:
OS: macOS 15.5
CPU: (10) arm64 Apple M2 Pro
Memory: 65.67 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.11.0 - ~/.volta/tools/image/node/22.11.0/bin/node
Yarn: 1.22.22 - ~/.volta/tools/image/yarn/1.22.22/bin/yarn
npm: 10.9.0 - ~/.volta/tools/image/node/22.11.0/bin/npm
pnpm: 10.8.0 - ~/.volta/tools/image/pnpm/10.8.0/bin/pnpm
bun: 1.0.3 - ~/.bun/bin/bun
Watchman: 2025.04.28.00 - /opt/homebrew/bin/watchman
Browsers:
Safari: 18.5
npmPackages:
livekit-client: ^2.13.5 => 2.13.5
Severity
serious, but I can work around it
Additional Information
I am currently processing connected, reconnecting, and reconnected events to get a relevant error. If the reconnecting process starts and there are no connected or reconnected events, then I treat the received DUPLICATE_IDENTITY error as a server unavailable error in order to switch to some fallback option.
Thanks for the report!
Just to clarify the usage pattern, when and how is your app calling room.connect() ?
Especially interested in any connect calls that happen as part of a useEffect in react or something similar.
Also any manual reconnection handling when e.g. calling connect() as a result of Reconnecting would be interesting.
If you happen to have full debug browser console logs of a session that reproduces the behaviour that would be great!
For reproduction, I use the JS SDK directly in an Ember.js application, and connect is triggered only once when the entire DOM is loaded. Here's the minimal code I used for reproduction:
import type { RoomConnectOptions } from 'livekit-client';
import { DisconnectReason, Room, RoomEvent } from 'livekit-client';
export default class LivekitRoom {
private room: Room;
constructor() {
this.room = new Room();
}
_isConnected = false;
connect = async (url: string, token: string, opts?: RoomConnectOptions) => {
this.setUpEventListeners(this.room);
await this.room.connect(url, token, {
maxRetries: 3,
...opts,
});
};
public async destroy() {
await this.room.disconnect(true);
}
private setUpEventListeners(room: Room) {
room.on(RoomEvent.Disconnected, this.handlerDisconnected)
.on(RoomEvent.Reconnecting, this.onReconnecting)
.on(RoomEvent.Reconnected, this.onReconnected);
}
_isReconnecting = false;
onReconnecting = () => {
this._isReconnecting = true;
};
onReconnected = () => {
this._isReconnecting = false;
};
private handlerDisconnected = (reason?: DisconnectReason) => {
if (reason === DisconnectReason.DUPLICATE_IDENTITY) {
if (!this._isConnected && this._isReconnecting) {
const error = new Error(
'Livekit connection failed, probably a problem with livekit cloud, info:' +
JSON.stringify(this.room.serverInfo || {}),
);
console.error(error);
}
}
console.log('Livekit room disconnected', reason);
};
}
window.addEventListener('load', function () {
const room = new LivekitRoom();
room.connect();
});
Errors is dev console:
resuming signal connection, attempt 0
Initial connection failed with ConnectionError: could not establish pc connection. Retrying with another region: https://allright.dfra1b.production.livekit.cloud/
resuming signal connection, attempt 1
resuming signal connection, attempt 2
Livekit room disconnected: 2
Unfortunately, there's no current stack trace after the server issues were fixed.