RocketChat/Rocket.Chat · error · Meteor.Error

error-forwarding-department-target-not-allowed

error-forwarding-department-target-not-allowed

Error message

The forwarding to the target department is not allowed.

What it means

Thrown by the 'livechat.beforeForwardRoomToDepartment' hook when the department the room currently belongs to declares a non-empty departmentsAllowedToForward list and the target department is not in it. It enforces per-department forwarding ACLs: once a list exists, only listed departments may receive that room.

Solutions

  1. Add the target department to the current department's 'Forwarding allowed departments' (departmentsAllowedToForward) in Administration > Omnichannel Departments
  2. Or forward to one of the departments already present in the allowed list
  3. If restrictions are legacy, clear the departmentsAllowedToForward list (empty means unrestricted) on the current department

Example fix

// before: transferring straight into a restricted target
await transferRoom(rid, { departmentId: targetDeptId });

// after: check the current department's ACL the same way the hook does
const current = await LivechatDepartment.findOneById(room.departmentId, {
  projection: { departmentsAllowedToForward: 1 },
});
const allowed = current?.departmentsAllowedToForward ?? [];
if (allowed.length > 0 && !allowed.includes(targetDeptId)) {
  throw new Error('Target department not allowed for forwarding');
}
await transferRoom(rid, { departmentId: targetDeptId });
Defensive patterns

Strategy: validation

Validate before calling

const isForwardAllowed = (current: { departmentsAllowedToForward?: string[] }, targetId: string): boolean =>
  !current.departmentsAllowedToForward?.length || current.departmentsAllowedToForward.includes(targetId);

Try / catch

try {
  await transferRoom(rid, { departmentId: target });
} catch (err: any) {
  if (err?.error === 'error-forwarding-department-target-not-allowed') {
    // pick an allowed target or update the department's allow list
  }
  throw err;
}

Prevention

When it happens

Trigger: Forwarding/transferring an omnichannel room to department B while the room's current department A has departmentsAllowedToForward = [C, D]; REST API livechat.transfer or the UI transfer widget targeting a non-allowed department.

Common situations: Department-level forwarding restrictions configured after workflows were built; new departments created but never added to allowed lists; automation scripts transferring to a hard-coded departmentId that is no longer allowed.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/0aeb240d4b331e1a. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/ee/server/hooks/omnichannel/beforeForwardRoomToDepartment.ts:32

		const { departmentId } = room;
		if (!departmentId) {
			return options;
		}
		const { department: departmentToTransfer } = transferData;
		const currentDepartment = await LivechatDepartment.findOneById<Pick<ILivechatDepartment, 'departmentsAllowedToForward'>>(departmentId, {
			projection: { departmentsAllowedToForward: 1 },
		});
		if (!currentDepartment) {
			return options;
		}
		const { departmentsAllowedToForward } = currentDepartment;
		const isAllowedToTransfer =
			!departmentsAllowedToForward?.length ||
			(Array.isArray(departmentsAllowedToForward) && departmentsAllowedToForward.includes(departmentToTransfer._id));
		if (isAllowedToTransfer) {
			return options;
		}
		throw new Meteor.Error('error-forwarding-department-target-not-allowed', 'The forwarding to the target department is not allowed.');
	},
	callbacks.priority.HIGH,
	'livechat-before-forward-room-to-department',
);

View on GitHub (pinned to b2c16d5842)