RocketChat/Rocket.Chat · error · Meteor.Error

error-validating-department-chat-closing-tags

error-validating-department-chat-closing-tags

Error message

At least one closing tag is required when the department requires tag(s) on closing conversations.

What it means

Thrown by `livechat:saveDepartment` after the `check(departmentData, defaultValidations)` stage when `requestTagBeforeClosingChat` is truthy but `chatClosingTags` is missing, undefined, or an empty array. Closing tags are conditionally required: enabling 'require tag before closing chat' demands at least one selectable tag.

Source

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

	// The Livechat Form department support addition/custom fields, so those fields need to be added before validating
	Object.keys(departmentData).forEach((field) => {
		if (!defaultValidations.hasOwnProperty(field)) {
			defaultValidations[field] = Match.OneOf(String, Match.Integer, Boolean);
		}
	});

	check(departmentData, defaultValidations);
	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',
		);
	}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Provide at least one tag: `chatClosingTags: ['billing-issue']` in the departmentData payload
  2. Or keep `requestTagBeforeClosingChat: false` until tags are configured
  3. Add client-side form validation tying the 'require closing tags' switch to a non-empty tags list before calling the method

Example fix

// before
await saveDepartment(_id, { ...deptData, requestTagBeforeClosingChat: true }); // chatClosingTags missing

// after
await saveDepartment(_id, {
  ...deptData,
  requestTagBeforeClosingChat: true,
  chatClosingTags: deptData.chatClosingTags?.length ? deptData.chatClosingTags : ['support'],
});
Defensive patterns

Strategy: validation

Validate before calling

if (deptData.requestTagBeforeClosingChat && !deptData.chatClosingTags?.length) {
  throw new Error('Provide at least one closing tag or disable the requirement');
}
await saveDepartment(_id, deptData);

Type guard

const hasRequiredClosingTags = (d: { requestTagBeforeClosingChat?: boolean; chatClosingTags?: string[] }): boolean =>
  !d.requestTagBeforeClosingChat || (d.chatClosingTags?.length ?? 0) > 0;

Try / catch

try {
  await saveDepartment(_id, deptData);
} catch (e) {
  if (isMeteorError(e, 'error-validating-department-chat-closing-tags')) {
    // prompt user to add chatClosingTags or turn off requestTagBeforeClosingChat
  }
}

Prevention

When it happens

Trigger: Saving a department whose payload has `requestTagBeforeClosingChat: true` while `chatClosingTags` is absent, `[]`, or falsy — typically a form that lets agents toggle the 'require tags' switch without seeding the tag picker.

Common situations: New department forms where the closing-tags input is optional and left empty; API integrations that copy a template department and strip the tags array; toggling the setting on an existing department that never had tags.

Related errors


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