RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

Thrown by executeArchiveRoom when the acting user cannot be used for archiving: Users.findOneById(userId) found no document, or the document fails isRegisterUser (not a plain active registered user, e.g. app/bot or deactivated accounts). Rocket.Chat requires a registered user because that user is recorded as archiving the room. The DDP wrapper has already confirmed a logged-in connection before calling this helper, so hitting this line means the account behind the session is missing or not a regular registered user.

Source

Thrown at apps/meteor/server/meteor-methods/rooms/archiveRoom.ts:25

import { RoomMemberActions } from '../../../definition/IRoomTypeConfig';
import { hasPermissionAsync } from '../../lib/authorization/hasPermission';
import { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';
import { archiveRoom } from '../../lib/rooms/archiveRoom';
import { roomCoordinator } from '../../lib/rooms/roomCoordinator';

declare module '@rocket.chat/ddp-client' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		archiveRoom(rid: string): Promise<void>;
	}
}

export const executeArchiveRoom = async (userId: string, rid: string) => {
	check(rid, String);

	const user = await Users.findOneById(userId, { projection: { username: 1, name: 1 } });
	if (!user || !isRegisterUser(user)) {
		throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'archiveRoom' });
	}

	const room = await Rooms.findOneById(rid);
	if (!room) {
		throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'archiveRoom' });
	}

	if (!(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId))) {
		throw new Meteor.Error('error-direct-message-room', `rooms type: ${room.t} can not be archived`, { method: 'archiveRoom' });
	}

	if (!(await hasPermissionAsync(userId, 'archive-room', room._id))) {
		throw new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'archiveRoom' });
	}

	return archiveRoom(rid, user);
};

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the acting account first: it must exist and satisfy isRegisterUser (plain user type, active).
  2. If the session went stale, log out and back in so the connection carries a fresh, valid userId.
  3. Replace the deprecated DDP method with POST /api/v1/channels.archive using valid X-Auth-Token/X-User-Id headers.

Example fix

// before
await executeArchiveRoom(appUserId, rid); // appUserId belongs to an app/bot account

// after
const user = await Users.findOneById(userId, { projections: { type: 1, active: 1 } });
if (!user || !isRegisterUser(user)) {
  throw new Error('Acting user is not a registered user');
}
await executeArchiveRoom(userId, rid);
Defensive patterns

Strategy: try-catch

Validate before calling

const me = Meteor.user();
if (!me) {
  // no account on this connection - re-login before calling archiveRoom
}

Type guard

const isRegisteredAccount = (u: { type?: string; active?: boolean } | null | undefined): u is { type: string; active: boolean } =>
  !!u && u.type === 'user' && u.active === true;

Try / catch

try {
  await Meteor.callAsync('archiveRoom', rid);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {
    // account missing or not registered: end the session and re-authenticate
    await Meteor.logout();
    goToLogin();
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Meteor.call('archiveRoom', rid) while the acting account was deleted or deactivated after login; server-side reuse of executeArchiveRoom(userId, rid) with a nonexistent or app/bot user _id; test fixtures that insert users without the active/type fields isRegisterUser requires.

Common situations: Custom integrations passing an app or system user id; admin deactivating a user while their session is still alive; LDAP/OAuth accounts disabled upstream but sessions not purged; unit tests seeding bare user records.

Related errors


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