RocketChat/Rocket.Chat · error · Meteor.Error

error-department-not-found

error-department-not-found

Error message

Department not found

What it means

Thrown by `livechat:saveDepartment` when an `_id` was supplied (edit path) but `LivechatDepartment.findOneById(_id)` (executed earlier in saveDepartment) returned null. The method treats a supplied id as a promise the document exists; a missing one aborts before `createOrUpdateDepartment` could accidentally insert with a caller-chosen id.

Source

Thrown at apps/meteor/server/lib/omnichannel/departmentsLib.ts:104

	check(
		departmentAgents,
		Match.Maybe({
			upsert: Match.Maybe(Array),
			remove: Match.Maybe(Array),
		}),
	);

	const { requestTagBeforeClosingChat, chatClosingTags, fallbackForwardDepartment } = departmentData;
	if (requestTagBeforeClosingChat && (!chatClosingTags || chatClosingTags.length === 0)) {
		throw new Meteor.Error(
			'error-validating-department-chat-closing-tags',
			'At least one closing tag is required when the department requires tag(s) on closing conversations.',
			{ method: 'livechat:saveDepartment' },
		);
	}

	if (_id && !department) {
		throw new Meteor.Error('error-department-not-found', 'Department not found', {
			method: 'livechat:saveDepartment',
		});
	}

	if (fallbackForwardDepartment === _id) {
		throw new Meteor.Error(
			'error-fallback-department-circular',
			'Cannot save department. Circular reference between fallback department and department',
		);
	}

	if (fallbackForwardDepartment) {
		const fallbackDep = await LivechatDepartment.findOneById<Pick<ILivechatDepartment, '_id'>>(fallbackForwardDepartment, {
			projection: { _id: 1 },
		});
		if (!fallbackDep) {
			throw new Meteor.Error('error-fallback-department-not-found', 'Fallback department not found', {
				method: 'livechat:saveDepartment',

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Re-fetch the department list (`GET /v1/livechat/department`) and retry with the current id, or create a new department if it was deleted
  2. Guard the save with an existence check (`LivechatDepartment.findOneById`) and treat this error as 'deleted elsewhere' in the UI
  3. For integrations, stop hard-coding department ids; resolve by name at runtime

Example fix

// before
await saveDepartment(staleId, deptData);

// after
const dep = await LivechatDepartment.findOneById(staleId, { projection: { _id: 1 } });
if (!dep) throw new Error('Department was deleted; reload the list');
await saveDepartment(staleId, deptData);
Defensive patterns

Strategy: validation

Validate before calling

const dep = await LivechatDepartment.findOneById(_id, { projection: { _id: 1 } });
if (!dep) throw new Error('Department no longer exists — reload');
await saveDepartment(_id, deptData);

Type guard

const departmentExists = async (id: string): Promise<boolean> =>
  (await LivechatDepartment.findOneById(id, { projection: { _id: 1 } })) != null;

Try / catch

try {
  await saveDepartment(_id, deptData);
} catch (e) {
  if (isMeteorError(e, 'error-department-not-found')) {
    // refresh list; offer create-new flow
  }
}

Prevention

When it happens

Trigger: `livechat:saveDepartment` / REST `PUT /v1/livechat/department/{_id}` where the id was deleted in another session, is a typo/truncated string, or comes from an environment that was re-seeded and no longer has that document.

Common situations: Editing a department in two admin tabs where one deletes it; stale department ids cached by integrations after a database restore; copy-paste of ids between environments (dev/prod).

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/0039202f5c574ef8. Report an issue: GitHub.