RocketChat/Rocket.Chat · error · Error

visitor-not-found

Error message

visitor-not-found

What it means

Thrown by findVisitorInfo (visitors.ts:8-12) when LivechatVisitors.findOneEnabledById(visitorId) returns null. This means either no visitor exists with that `_id`, or the visitor record exists but is disabled (the query uses the *Enabled* variant). The token field is projected out of the result. Returns HTTP 400 { success:false, error:'visitor-not-found' }.

Source

Thrown at apps/meteor/server/api/v1/omnichannel/lib/visitors.ts:11

import type { ILivechatVisitor, IMessage, IOmnichannelRoom, IRoom, IUser, IVisitor } from '@rocket.chat/core-typings';
import { LivechatVisitors, Messages, LivechatRooms, LivechatCustomField } from '@rocket.chat/models';
import type { FindOptions } from 'mongodb';

import { canAccessRoomAsync } from '../../../../lib/authorization/canAccessRoom';
import { callbacks } from '../../../../lib/callbacks';

export async function findVisitorInfo({ visitorId }: { visitorId: IVisitor['_id'] }) {
	const visitor = await LivechatVisitors.findOneEnabledById(visitorId, { projection: { token: 0 } });
	if (!visitor) {
		throw new Error('visitor-not-found');
	}

	return {
		visitor,
	};
}

export async function findVisitedPages({
	roomId,
	pagination: { offset, count, sort },
}: {
	roomId: IRoom['_id'];
	pagination: { offset: number; count: number; sort: FindOptions<IMessage>['sort'] };
}) {
	const room = await LivechatRooms.findOneById(roomId);
	if (!room) {
		throw new Error('invalid-room');
	}

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Confirm the visitor exists and is enabled via LivechatVisitors.findOneEnabledById before calling.
  2. Do not confuse visitor `token` with visitor `_id`; this function takes `_id`.
  3. If the visitor was disabled/deleted, restore or recreate it.

Example fix

// before
const { visitor } = await findVisitorInfo({ visitorId: maybeAToken }); // throws visitor-not-found

// after
const visitor = await LivechatVisitors.findOneEnabledById(visitorId);
if (!visitor) return notFound();
const info = await findVisitorInfo({ visitorId: visitor._id });
Defensive patterns

Strategy: validation

Validate before calling

const visitor = await LivechatVisitors.findOneEnabledById(visitorId);
if (!visitor) {
  throw new Error('visitor does not exist or is disabled');
}
// safe to call findVisitorInfo({ visitorId })

Type guard

const visitorExists = async (id: string) => !!(await LivechatVisitors.findOneEnabledById(id, { projection: { _id: 1 } }));

Try / catch

try {
  await findVisitorInfo({ visitorId });
} catch (e) {
  if (e instanceof Error && e.message === 'visitor-not-found') {
    // 404 to client or recreate the visitor
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling findVisitorInfo / the visitor-info endpoint with a visitorId that does not exist or has been disabled.

Common situations: Passing the visitor `token` where the visitor `_id` is expected; visitor disabled via contact-merge or GDPR/right-to-erasure deletion; stale id persisted client-side.

Related errors


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