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
- Confirm the visitor exists and is enabled via LivechatVisitors.findOneEnabledById before calling.
- Do not confuse visitor `token` with visitor `_id`; this function takes `_id`.
- 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
- Pass the visitor `_id`, never the `token`, to findVisitorInfo.
- Treat disabled visitors as not-found; restore or recreate instead of retrying.
- Validate the id shape/source before calling.
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.