RocketChat/Rocket.Chat · error · Error

error-invalid-inquiry

Error message

error-invalid-inquiry

What it means

Thrown by resumeRoomOnHold (omnichannel.internalService.ts:107) after the state checks pass: the service loads the room's LivechatInquiry via LivechatInquiry.findOneByRoomId(roomId) and gets null. Every livechat room must have a matching inquiry record to re-assign or queue the chat; a missing one means deleted or inconsistent data.

Solutions

  1. Before resuming, verify the inquiry exists: LivechatInquiry.findOneByRoomId(rid) — if absent, do not attempt resume
  2. Inspect the database for the room/inquiry pair and repair or close the orphaned room
  3. Check server logs ('No inquiry found for room') to identify which roomId is affected and trace which flow deleted its inquiry

Example fix

// before
await omnichannelService.resumeRoomOnHold(room, comment, agent);

// after
const inquiry = await LivechatInquiry.findOneByRoomId(room._id, { projection: { _id: 1 } });
if (!inquiry) {
	throw new Error('error-invalid-inquiry'); // or close the orphan room explicitly
}
await omnichannelService.resumeRoomOnHold(room, comment, agent);
Defensive patterns

Strategy: validation

Validate before calling

const inquiry = await LivechatInquiry.findOneByRoomId(rid, { projection: { _id: 1 } });
if (!inquiry) {
	// orphan room — close it or alert; do not resume
	throw new Error('error-invalid-inquiry');
}
await omnichannelService.resumeRoomOnHold(room, comment, agent);

Try / catch

try {
	await omnichannelService.resumeRoomOnHold(room, comment, agent);
} catch (e) {
	if (e instanceof Error && e.message === 'error-invalid-inquiry') {
		// data inconsistency: close the orphaned room instead of retrying
	}
	throw e;
}

Prevention

When it happens

Trigger: Resuming an on-hold room whose inquiry record does not exist — the inquiry was deleted by another flow (contact/visitor deletion, cleanup job) or the room/inquiry pair is inconsistent (orphan room).

Common situations: Orphaned livechat rooms after failed migrations or manual DB surgery; inquiry removed by a concurrent operation while the room stayed on hold; environments restored from partial backups.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — 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/b3b74b29936e6306. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/ee/server/local-services/omnichannel.internalService.ts:107

		if (!room.open) {
			throw new Error('This_conversation_is_already_closed');
		}

		if (!room.onHold) {
			throw new Error('error-room-not-on-hold');
		}

		const { _id: roomId, servedBy } = room;

		if (!servedBy) {
			this.logger.error({ msg: 'No serving agent found for room', roomId });
			throw new Error('error-room-not-served');
		}

		const inquiry = await LivechatInquiry.findOneByRoomId(roomId, {});
		if (!inquiry) {
			this.logger.error({ msg: 'No inquiry found for room', roomId });
			throw new Error('error-invalid-inquiry');
		}

		await this.attemptToAssignRoomToServingAgentElseQueueIt({
			room,
			inquiry,
			servingAgent: servedBy,
			clientAction,
		});

		const [roomResult, subsResult] = await Promise.all([
			LivechatRooms.unsetOnHoldByRoomId(roomId),
			Subscriptions.unsetOnHoldByRoomId(roomId),
			Message.saveSystemMessage<IOmnichannelSystemMessage>('omnichannel_on_hold_chat_resumed', roomId, '', resumeBy, { comment }),
		]);

		if (roomResult.modifiedCount) {
			void notifyOnRoomChangedById(roomId);
		}

View on GitHub (pinned to b2c16d5842)