RocketChat/Rocket.Chat · error · Error
This_conversation_is_already_closed
This_conversation_is_already_closed
Error message
This_conversation_is_already_closed
What it means
Thrown by the POST livechat/room.forward endpoint when the target Livechat room exists but has room.open === false, meaning the conversation was already closed. Rocket.Chat blocks transfers on closed rooms because the agent assignment and routing pipeline only operates on active omnichannel sessions. The guard fires before MAC, visitor, and transfer logic so a closed conversation fails fast.
Source
Thrown at apps/meteor/server/api/v1/omnichannel/room.ts:300
);
API.v1.addRoute(
'livechat/room.forward',
{ authRequired: true, permissionsRequired: ['view-l-room', 'transfer-livechat-guest'], validateParams: isLiveChatRoomForwardProps },
{
async post() {
const transferData = this.bodyParams as typeof this.bodyParams & {
transferredBy: TransferByData;
transferredTo?: { _id: string; username?: string; name?: string };
};
const room = await LivechatRooms.findOneById(this.bodyParams.roomId);
if (room?.t !== 'l') {
throw new Error('error-invalid-room');
}
if (!room.open) {
throw new Error('This_conversation_is_already_closed');
}
if (!(await Omnichannel.isWithinMACLimit(room))) {
throw new Error('error-mac-limit-reached');
}
const guest = await LivechatVisitors.findOneEnabledById(room.v?._id);
if (!guest) {
throw new Error('error-invalid-visitor');
}
transferData.transferredBy = normalizeTransferredByData(this.user, room);
if (transferData.userId) {
const userToTransfer = await Users.findOneById(transferData.userId);
if (userToTransfer) {
transferData.transferredTo = {
_id: userToTransfer._id,
username: userToTransfer.username,View on GitHub (pinned to f9d3ec372b)
Solutions
- Before calling room.forward, fetch the room (GET livechat/rooms or livechat/room.open state) and verify room.open === true; abort the transfer UI if closed.
- Handle this specific error in the client by refreshing the room list and showing 'Conversation already closed' instead of retrying.
- If reopening is intended, call livechat/room.open first, then retry the forward.
- Audit close callbacks/webhooks firing earlier than expected (e.g. Livechat_room_inactivity_period, Livechat_room_close_on_agent_offline).
Example fix
// before
await POST('/api/v1/livechat/room.forward', { roomId, userId });
// after
const room = await GET('/api/v1/livechat/rooms', { query: JSON.stringify({ _id: roomId }) });
if (!room.open) {
notifyUser('Conversation already closed');
return;
}
await POST('/api/v1/livechat/room.forward', { roomId, userId }); Defensive patterns
Strategy: validation
Validate before calling
const room = await LivechatRooms.findOneById(roomId, { projection: { open: 1, t: 1 } });
if (!room || room.t !== 'l') throw new ClientError('invalid-room');
if (!room.open) throw new ClientError('room-closed');
// now safe to call POST livechat/room.forward Type guard
const isForwardableRoom = (r: unknown): r is { open: true; t: 'l'; _id: string } =>
!!r && typeof r === 'object' && (r as any).t === 'l' && (r as any).open === true && typeof (r as any)._id === 'string'; Try / catch
try {
await POST('/api/v1/livechat/room.forward', { roomId, userId });
} catch (e) {
if (e.message === 'This_conversation_is_already_closed') { refreshRoomList(); notifyClosed(); return; }
throw e;
} Prevention
- Refresh the room's open state before exposing transfer/cancel actions in the UI.
- Treat close callbacks (webhooks, inactivity) as authoritative and invalidate cached room state.
- Disable the transfer button immediately when the local room.open flag flips to false.
When it happens
Trigger: POST /api/v1/v1/livechat/room.forward with a bodyParams.roomId that resolves to a Livechat room whose `open` field is false. Happens when the client holds a stale roomId after the room was closed via agent close, inactivity timeout, omnichannel callback, or a prior transfer that closed the source room.
Common situations: UI keeps a room list cached after an agent closes a chat and the user clicks 'transfer'; race between a close callback (e.g. webhook/timeout) and the transfer click; integration replaying a roomId from an earlier session; agent has the room open in a tab while another agent closes it.
Related errors
- error-room-already-closed
- This_conversation_is_already_closed
- error-invalid-room
- error-invalid-sla
- error-forwarding-department-target-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/cdb835192b1c0e70.
Report an issue: GitHub.