RocketChat/Rocket.Chat · error · Meteor.Error

invalid-user

invalid-user

Error message

Invalid user

What it means

Thrown by setRoomAvatar when isRegisterUser(user) is false (setRoomAvatar.ts:12). isRegisterUser (packages/core-typings/src/IUser.ts:255) requires BOTH user.username and user.name to be defined — so this fires for incomplete user objects, not just missing accounts. Code is 'invalid-user' (no error- prefix), details { function: 'RocketChat.setRoomAvatar' }.

Source

Thrown at apps/meteor/server/lib/rooms/setRoomAvatar.ts:12

import { api, Message } from '@rocket.chat/core-services';
import type { IUser } from '@rocket.chat/core-typings';
import { isRegisterUser } from '@rocket.chat/core-typings';
import { Avatars, Rooms } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { RocketChatFile } from '../media/file';
import { FileUpload } from '../media/file-upload';

export const setRoomAvatar = async function (rid: string, dataURI: string, user: IUser): Promise<void> {
	if (!isRegisterUser(user)) {
		throw new Meteor.Error('invalid-user', 'Invalid user', {
			function: 'RocketChat.setRoomAvatar',
		});
	}

	const fileStore = FileUpload.getStore('Avatars');

	const current = await Avatars.findOneByRoomId(rid);

	if (!dataURI) {
		await fileStore.deleteByRoomId(rid);
		await Message.saveSystemMessage('room_changed_avatar', rid, '', user);
		void api.broadcast('room.avatarUpdate', { _id: rid });
		await Rooms.unsetAvatarData(rid);
		return;
	}

	const fileData = RocketChatFile.dataURIParse(dataURI);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Fetch the full user document before calling: Users.findOneById(userId)
  2. Ensure the user has both username and name set (update the profile if name is empty)
  3. Pre-check with the same helper: isRegisterUser(user) from '@rocket.chat/core-typings'
  4. Note the code is 'invalid-user', not 'error-invalid-user' — match on the exact string when catching

Example fix

// before
await setRoomAvatar(rid, dataURI, { _id: uid } as IUser);

// after
const user = await Users.findOneById(uid);
if (!user || !isRegisterUser(user)) {
	throw new Meteor.Error('invalid-user', 'Invalid user');
}
await setRoomAvatar(rid, dataURI, user);
Defensive patterns

Strategy: type-guard

Validate before calling

const user = await Users.findOneById(userId);
if (!user || !isRegisterUser(user)) {
	throw new Meteor.Error('invalid-user', 'A registered user (with username and name) is required');
}
await setRoomAvatar(rid, dataURI, user);

Type guard

import { isRegisterUser } from '@rocket.chat/core-typings';
// isRegisterUser: user.username !== undefined && user.name !== undefined
const assertRegisterUser = (u: IUser): void => {
	if (!isRegisterUser(u)) throw new Meteor.Error('invalid-user', 'User lacks username or name');
};

Prevention

When it happens

Trigger: Passing a partial user (e.g. picked from a session with only _id); app/bot users whose document lacks name; a user object constructed by hand in tests without name; code that passed userId string instead of the IUser document.

Common situations: Custom avatar endpoints resolving only {_id, username} from a token; importers creating users without a display name; refactors that swapped the full user param for AtLeast<IUser,'_id'>.

Related errors


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