RocketChat/Rocket.Chat · error · Error

error-forwarding-chat

error-forwarding-chat

Error message

error-forwarding-chat

What it means

Thrown by POST livechat/room.forward when the transfer(room, guest, transferData) helper returns a falsy result. The transfer helper can fail to route because the target department has no online agents, the target user is invalid, or internal routing rejects the move. This is a downstream failure after all preconditions passed.

Source

Thrown at apps/meteor/server/api/v1/omnichannel/room.ts:326

			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,
						name: userToTransfer.name,
					};
				}
			}

			const chatForwardedResult = await transfer(room, guest, transferData);
			if (!chatForwardedResult) {
				throw new Error('error-forwarding-chat');
			}

			return API.v1.success();
		},
	},
);

const livechatVisitorDepartmentTransfer = API.v1.post(
	'livechat/visitor/department.transfer',
	{
		response: {
			200: ajv.compile<void>({
				type: 'object',
				properties: {
					success: {
						type: 'boolean',
						enum: [true],
					},

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Confirm the target agent is online, has the livechat-agent role, and belongs to the target department.
  2. Enable Livechat_accept_chats_with_no_agents or configure department fallback if the department is frequently empty.
  3. Inspect server logs around the transfer() call for the specific internal reason it returned falsy.
  4. Retry after correcting the target; if it still fails, transfer to a queue/department instead of a specific user.

Example fix

// before
await POST('/api/v1/livechat/room.forward', { roomId, userId: targetId });

// after
if (!await isAgentOnlineAndInDepartment(targetId, departmentId)) {
  await POST('/api/v1/livechat/room.forward', { roomId, departmentId }); // queue to dept
} else {
  await POST('/api/v1/livechat/room.forward', { roomId, userId: targetId });
}
Defensive patterns

Strategy: try-catch

Validate before calling

const agent = await Users.findOneById(targetUserId);
if (!agent || !agent.roles?.includes('livechat-agent')) throw new ClientError('target-not-agent');
if (!await isAgentOnlineInDepartment(targetUserId, departmentId)) throw new ClientError('target-unavailable');

Type guard

null

Try / catch

try {
  await POST('/api/v1/livechat/room.forward', { roomId, userId });
} catch (e) {
  if (e.message === 'error-forwarding-chat') {
    logTransferFailure(roomId, targetUserId);
    await POST('/api/v1/livechat/room.forward', { roomId, departmentId }); // fallback to dept queue
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: POST livechat/room.forward where transfer() returns null/false: target department offline with no fallback, target userId references a non-agent or disabled user, or the routing callback aborted the transfer.

Common situations: Department has no online agents and Livechat_accept_chats_with_no_agents is false; transferredTo.userId resolves to a user without the livechat-agent role; a callback in the transfer pipeline (e.g. livechat.transfer') blocked the move; transient race where the room was closed between the open-check and transfer().

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/32f56929dc076b97. Report an issue: GitHub.