RocketChat/Rocket.Chat · error · Error
visitor-not-found
Error message
visitor-not-found
What it means
findVisitorInfo (backing GET /api/v1/livechat/visitors/:visitorId, the visitor-info detail call) uses LivechatVisitors.findOneEnabledById(visitorId). It throws 'visitor-not-found' when no document exists with that _id or the visitor is disabled (findOneEnabledById filters out visitors no longer enabled).
Solutions
- Re-discover the visitor via the authenticated visitors search/list endpoint and copy the exact _id.
- If the visitor was blocked or disabled intentionally, treat this as a 404 and stop showing detail.
- Confirm you are querying the same server/environment that produced the id.
Defensive patterns
Strategy: validation
Validate before calling
const OBJ_ID = /^[0-9a-f]{24}$/i;
function isVisitorId(v: string): boolean { return OBJ_ID.test(v); }
if (!isVisitorId(visitorId)) throw new TypeError('malformed visitorId');
const { visitors } = await get(`/api/v1/livechat/visitors?term=${encodeURIComponent(nameOrEmail)}`);
const exact = visitors.find((v) => v._id === visitorId);
if (!exact) throw new NotFoundError('visitor missing or disabled');
const { visitor } = await getVisitorInfo(visitorId); Try / catch
try { visitor = await getVisitorInfo(visitorId); } catch (e) { if (e.message === 'visitor-not-found') return renderNotFound(); throw e; } Prevention
- Treat visitor-not-found as expected for blocked/disabled visitors; render empty state.
- Refresh ids from search rather than caching them long-term.
- Remember the lookup is enabled-only: disabled visitors behave like deleted ones.
When it happens
Trigger: Requesting visitor detail with a mistyped/truncated _id; the visitor record was deleted; the visitor is disabled (e.g. blocked via the omnichannel block/visitor management) so the enabled-only query skips it.
Common situations: Ids copied between environments; visitor cleaned up by retention/GDPR tooling after the UI captured the id; blocked visitors still listed in a stale client cache.
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
- agent-not-found
- error-forwarding-chat
- error-invalid-department-unit
- error-invalid-room
- error-invalid-user
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/d926e682a900e1a4.
Report an issue: GitHub.
Appendix: 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 b2c16d5842)