RocketChat/Rocket.Chat · error · Error

error-comment-is-required

error-comment-is-required

Error message

error-comment-is-required

What it means

doCloseRoom reads the workspace setting 'Livechat_request_comment_when_closing_conversation'; when enabled, closing an omnichannel room without a non-blank comment throws Error('error-comment-is-required'). The check uses comment?.trim(), so whitespace-only comments are rejected too.

Source

Thrown at apps/meteor/server/lib/omnichannel/closeRoom.ts:141

	logger.debug({ msg: 'Room was closed', roomId: newRoom._id });
}

async function doCloseRoom(
	params: CloseRoomParams,
	session: ClientSession,
): Promise<{ room: IOmnichannelRoom; closedBy: ChatCloser; removedInquiry: ILivechatInquiryRecord | null }> {
	const { comment } = params;
	const { room, forceClose } = params;

	logger.debug({ msg: 'Attempting to close room', roomId: room._id, forceClose });
	if (!room || !isOmnichannelRoom(room) || (!forceClose && !room.open)) {
		logger.debug({ msg: 'Room is not open', roomId: room._id });
		throw new Error('error-room-closed');
	}

	const commentRequired = settings.get('Livechat_request_comment_when_closing_conversation');
	if (commentRequired && !comment?.trim()) {
		throw new Error('error-comment-is-required');
	}

	const { updatedOptions: options } = await resolveChatTags(room, params.options);
	logger.debug({ msg: 'Resolved chat tags for room', roomId: room._id });

	const now = new Date();
	const { _id: rid, servedBy } = room;
	const serviceTimeDuration = servedBy && (now.getTime() - new Date(servedBy.ts).getTime()) / 1000;

	const closeData: IOmnichannelRoomClosingInfo = {
		closedAt: now,
		chatDuration: (now.getTime() - new Date(room.ts).getTime()) / 1000,
		...(serviceTimeDuration && { serviceTimeDuration }),
		...options,
	};
	logger.debug({ msg: 'Room was closed', roomId: room._id, closedAt: closeData.closedAt, chatDuration: closeData.chatDuration });

	if (isRoomClosedByUserParams(params)) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Pass a non-empty comment (e.g. a closing reason) whenever closing rooms while the setting is enabled
  2. If comments are not required by policy, disable Livechat_request_comment_when_closing_conversation
  3. For bulk closes, always supply a default comment such as 'Closed in bulk'

Example fix

// before - throws when the setting is enabled
await closeRoom({ room, user });

// after
await closeRoom({ room, user, comment: 'Resolved - no further response needed' });
Defensive patterns

Strategy: validation

Validate before calling

import { settings } from '../../../settings/server';

const commentRequired = settings.get('Livechat_request_comment_when_closing_conversation');
if (commentRequired && !comment?.trim()) {
  // block the close or supply a default comment before calling closeRoom
}

Try / catch

try {
  await closeRoom({ room, user, comment });
} catch (err: any) {
  if (err?.message === 'error-comment-is-required') return promptForComment(room);
  throw err;
}

Prevention

When it happens

Trigger: Closing a livechat room via UI, REST, or server flow with the setting enabled while the comment is omitted, empty, or spaces only; bulk closes that pass no comment while the setting is on.

Common situations: The setting was enabled after integrations were written that close rooms without comments; bulk close of all open chats with no comment parameter; custom agent clients that skip the comment field in their close payload.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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