RocketChat/Rocket.Chat · error · Error
error-invalid-user
error-invalid-user
Error message
error-invalid-user
What it means
Thrown by GET livechat/room.join when this.user is null/undefined. The route declares authRequired: true, so the framework should populate this.user from the authenticated session; if it is still missing the authenticated principal could not be resolved to a user document. This is essentially an auth-resolution failure after the auth middleware ran.
Source
Thrown at apps/meteor/server/api/v1/omnichannel/room.ts:412
);
type LivechatAnalyticsEndpoints = ExtractRoutesFromAPI<typeof livechatVisitorDepartmentTransfer>;
declare module '@rocket.chat/rest-typings' {
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
interface Endpoints extends LivechatAnalyticsEndpoints {}
}
API.v1.addRoute(
'livechat/room.join',
{ authRequired: true, permissionsRequired: ['view-l-room'], validateParams: isLiveChatRoomJoinProps },
{
async get() {
const { roomId } = this.queryParams;
const { user } = this;
if (!user) {
throw new Error('error-invalid-user');
}
const room = await LivechatRooms.findOneById(roomId);
if (!room) {
throw new Error('error-invalid-room');
}
if (!room.open) {
throw new Error('room-closed');
}
if (!(await Omnichannel.isWithinMACLimit(room))) {
throw new Error('error-mac-limit-reached');
}
if (!(await canAccessRoomAsync(room, user))) {
throw new Error('error-not-allowed');View on GitHub (pinned to f9d3ec372b)
Solutions
- Re-authenticate to obtain a fresh token for an active user account.
- Confirm the user account exists and is active (GET /api/v1/me) before calling room.join.
- If using a service account, ensure it is not deleted and still holds the required roles/permissions.
- Invalidate sessions for deleted users so the middleware rejects them before they reach the handler.
Example fix
// before
await GET('/api/v1/livechat/room.join', { roomId }, { headers: { 'X-Auth-Token': staleToken } });
// after
const me = await GET('/api/v1/me', { headers: { 'X-Auth-Token': token } });
if (!me) reauthenticate();
await GET('/api/v1/livechat/room.join', { roomId }, { headers: { 'X-Auth-Token': freshToken } }); Defensive patterns
Strategy: validation
Validate before calling
const me = await GET('/api/v1/me', { headers: authHeaders });
if (!me || !me._id) { await reauthenticate(); return; } Type guard
null
Try / catch
try {
await GET('/api/v1/livechat/room.join', { roomId });
} catch (e) {
if (e.message === 'error-invalid-user') { clearSession(); redirectToLogin(); return; }
throw e;
} Prevention
- Call /api/v1/me on app start to confirm the token resolves to a live user.
- Invalidate sessions server-side when users are deleted/deactivated.
- Avoid long-lived tokens for accounts that may be rotated out.
When it happens
Trigger: GET livechat/room.join?roomId=... with a token whose user was deleted between token issuance and the request, or with a malformed auth header that passed the middleware but resolved to no user object.
Common situations: User account deleted/deactivated while their session token was still valid; API client using a stale X-Auth-Token after the user was removed; a custom auth plugin that returns success without attaching a valid user; clock/token skew against the sessions collection.
Related errors
- error-not-allowed
- error-contact-not-found
- error-visitor-not-found
- error-invalid-inquiry
- error-invalid-sla
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/b51c565914ca157c.
Report an issue: GitHub.