RocketChat/Rocket.Chat · error · Error

error-invalid-department

error-invalid-department

Error message

error-invalid-department

What it means

transfer() validates transferData.departmentId when present: it loads LivechatDepartment.findOneById with a name projection, and if no department document matches it throws Error('error-invalid-department'). The department must exist at transfer time because its name is attached to the transfer data shown to agents/visitors.

Source

Thrown at apps/meteor/server/lib/omnichannel/transfer.ts:77

		await transfer(room, guest, {
			transferredBy,
			departmentId: guest.department,
		});
	}
}

export async function transfer(room: IOmnichannelRoom, guest: ILivechatVisitor, transferData: TransferData) {
	livechatLogger.debug({ msg: 'Transferring room', roomId: room._id, transferredBy: transferData?.transferredBy?._id });
	if (room.onHold) {
		throw new Error('error-room-onHold');
	}

	if (transferData.departmentId) {
		const department = await LivechatDepartment.findOneById<Pick<ILivechatDepartment, 'name' | '_id'>>(transferData.departmentId, {
			projection: { name: 1 },
		});
		if (!department) {
			throw new Error('error-invalid-department');
		}

		transferData.department = department;
		livechatLogger.debug({ msg: 'Transferring room to department', roomId: room._id, departmentId: transferData.department?._id });
	}

	return RoutingManager.transferRoom(room, guest, transferData);
}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. List current departments (livechat departments API / Administration > Omnichannel > Departments) and use a valid _id
  2. Refresh the department list in the transfer dialog before submitting
  3. If the department was deleted intentionally, update saved transfer targets/defaults that still reference it
  4. Verify the exact id spelling (department _id, not name) in API payloads

Example fix

// before
await transfer(room, guest, { departmentId, transferredBy });

// after
const department = await LivechatDepartment.findOneById(departmentId, { projection: { name: 1 } });
if (!department) throw new Meteor.Error('error-invalid-department');
await transfer(room, guest, { departmentId, transferredBy });
Defensive patterns

Strategy: validation

Validate before calling

import { LivechatDepartment } from '@rocket.chat/models';

const department = await LivechatDepartment.findOneById(departmentId, { projection: { name: 1 } });
if (!department) {
  throw new Meteor.Error('error-invalid-department', `Department ${departmentId} does not exist`);
}
await transfer(room, guest, { ...transferData, departmentId });

Try / catch

try {
  await transfer(room, guest, transferData);
} catch (err) {
  if (err instanceof Error && err.message === 'error-invalid-department') {
    // refresh the department list and make the agent re-pick
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Transferring a livechat room to a departmentId that has no LivechatDepartment document: a deleted department, a wrong/archived id from a stale UI list, or an id typo in API calls.

Common situations: Departments deleted while old transfer dialogs stayed open, clients caching department lists, integrations passing department ids from another environment, or transfers targeting archived departments.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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