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

  1. Re-authenticate to obtain a fresh token for an active user account.
  2. Confirm the user account exists and is active (GET /api/v1/me) before calling room.join.
  3. If using a service account, ensure it is not deleted and still holds the required roles/permissions.
  4. 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

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


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