RocketChat/Rocket.Chat · error · Meteor.Error
error-livechat-visitor-registration
error-livechat-visitor-registration
Error message
Error registering visitor
What it means
Thrown as Meteor.Error('error-livechat-visitor-registration', 'Error registering visitor') when registerGuest returns null. registerGuest returns null only when LivechatVisitors.updateOneByIdOrToken with upsert+returnDocument:'after' yields no document - i.e. the upsert matched nothing and the insertion did not produce a returned document (a persistence/index failure path).
Source
Thrown at apps/meteor/server/api/v1/omnichannel/visitor.ts:67
const guest = {
token,
...(id && { id }),
...(name && { name }),
...(email && { email }),
...(department && { department }),
...(username && { username }),
...(connectionData && { connectionData }),
...(phone && typeof phone === 'string' && { phone: { number: phone as string } }),
connectionData: normalizeHttpHeaderData(this.request.headers),
};
const visitor = await registerGuest(guest, {
shouldConsiderIdleAgent: settings.get<boolean>('Livechat_enabled_when_agent_idle'),
shouldConsiderOfflineAgent: settings.get<boolean>('Livechat_accept_chats_with_no_agents'),
});
if (!visitor) {
throw new Meteor.Error('error-livechat-visitor-registration', 'Error registering visitor', {
method: 'livechat/visitor',
});
}
const extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}, { userId: this.userId });
// If it's updating an existing visitor, it must also update the roomInfo
const rooms = await LivechatRooms.findOpenByVisitorToken(visitor?.token, {}, extraQuery).toArray();
await Promise.all(
rooms.map(
(room: IRoom) =>
visitor &&
saveRoomInfo(room, {
_id: visitor._id,
name: visitor.name,
phone: visitor.phone?.[0]?.phoneNumber,
livechatData: visitor.livechatData as { [k: string]: string },
}),
),View on GitHub (pinned to f9d3ec372b)
Solutions
- Retry the registration once with the same token (races are often transient).
- Inspect server logs for Mongo duplicate-key or write errors around the failure time.
- Validate the department field (if supplied) resolves to a real department, since registerGuest throws error-invalid-department for unknown departments.
- If reproducible, check LivechatVisitors collection indexes and the document for the given token.
Example fix
null
Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
try {
await registerVisitor();
} catch (e) {
if (e.error === 'error-livechat-visitor-registration') {
// wait briefly and retry once; races on the same token often clear
await new Promise(r => setTimeout(r, 200));
await registerVisitor();
} else throw e;
} Prevention
- Avoid concurrent register calls for the same visitor token from multiple tabs/widgets.
- Inspect server logs for the underlying Mongo error if the retry fails.
- Validate department field client-side to avoid registerGuest's error-invalid-department path.
When it happens
Trigger: POST livechat/visitor with a token that survives the empty-check but the visitor upsert does not return a document - for example a duplicate-key error on a unique index during upsert, an invalid department causing the upstream error-invalid-department to be thrown by registerGuest (different path), or a transient DB write failure swallowed into a null return.
Common situations: Concurrent visitor registration racing on the same token causing a unique index conflict; Mongo write transaction aborted; corrupted visitor document referenced by token/id.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/26c313af38d184f8.
Report an issue: GitHub.