RocketChat/Rocket.Chat · critical · Error

error-invalid-inquiry

Error message

error-invalid-inquiry

What it means

Thrown by runVerifyContactChannel after the contact merge transaction succeeds but LivechatInquiry.findOneByRoomId(roomId) returns null. The comment in code marks this as 'something is really wrong with the queue' — an inquiry is expected to exist for any omnichannel room in this flow. Throwing prevents carrying on a half-verified state where the contact was merged but no inquiry exists to re-queue.

Source

Thrown at apps/meteor/ee/server/patches/verifyContactChannel.ts:88

	const room = await LivechatRooms.findOneById(roomId);
	if (!room) {
		throw new Error('error-invalid-room');
	}

	const result = await _verifyContactChannel(params, room);

	logger.debug({ msg: 'Finding inquiry', roomId });

	// Note: we are not using the session here since allowing the transactional flow to be used inside the
	//       saveQueueInquiry function would require a lot of changes across the codebase, so if we fail here we
	//       will not be able to rollback the transaction. That is not a big deal since the contact will be properly
	//       merged and the inquiry will be saved in the queue (will need to be taken manually by an agent though).
	const inquiry = await LivechatInquiry.findOneByRoomId(roomId);
	if (!inquiry) {
		// Note: if this happens, something is really wrong with the queue, so we should throw an error to avoid
		//       carrying on a weird state.
		throw new Error('error-invalid-inquiry');
	}

	if (inquiry.status === LivechatInquiryStatus.VERIFYING) {
		logger.debug({ msg: 'Verifying inquiry', roomId });
		await QueueManager.verifyInquiry(inquiry, room);
	}

	logger.debug({
		msg: 'Contact channel has been verified and merged successfully',
		contactId,
		visitorId,
		roomId,
	});

	return result;
};

verifyContactChannel.patch(runVerifyContactChannel, () => License.hasModule('contact-id-verification'));

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Investigate why the inquiry is missing (audit logs, manual db deletion, failed migration).
  2. Re-create or restore the inquiry for the room so the queue is consistent.
  3. If the room is stale/closed, mark the verification as moot instead of continuing.
  4. Add a reconciliation job that repairs rooms whose inquiry is absent.
Defensive patterns

Strategy: try-catch

Validate before calling

async function inquiryExistsForRoom(roomId: string): Promise<boolean> {
  const inq = await LivechatInquiry.findOneByRoomId(roomId, { projection: { _id: 1 } });
  return Boolean(inq);
}

Try / catch

try {
  await verifyContactChannel(params);
} catch (e) {
  if (e.message === 'error-invalid-inquiry') {
    // page an admin / run a queue reconciliation job
  } else throw e;
}

Prevention

When it happens

Trigger: The room exists, the contact/channel merge committed, but the associated livechat inquiry document is missing — typically because it was removed, the room was never properly queued, or another worker already took and closed it.

Common situations: Queue corruption from a partial migration, manual DB deletion of inquiries, a previously failed take-inquiry that left no inquiry behind, or a room created outside the normal omnichannel queueing path.

Related errors


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