RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

Invalid user

What it means

Thrown by setUsernameWithValidation after Users.findOneById(userId) returns null: the userId passed to the method does not match any user document. It is the first precondition of the rename flow (setUsername.ts:36-40) and fires before the federation, permission, and availability checks. The Meteor.Error code is 'error-invalid-user' with { method: 'setUsername' } in the details.

Source

Thrown at apps/meteor/server/lib/users/setUsername.ts:39

import { addUserToRoom } from '../rooms/addUserToRoom';
import { joinDefaultChannels } from '../rooms/joinDefaultChannels';

const isUserInFederatedRooms = async (userId: string): Promise<boolean> => {
	const cursor = Subscriptions.findUserFederatedRoomIds(userId);
	const hasAny = await cursor.hasNext();
	await cursor.close();
	return hasAny;
};

export const setUsernameWithValidation = async (userId: string, username: string, joinDefaultChannelsSilenced?: boolean): Promise<void> => {
	if (!username) {
		throw new Meteor.Error('error-invalid-username', 'Invalid username', { method: 'setUsername' });
	}

	const user = await Users.findOneById(userId);

	if (!user) {
		throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'setUsername' });
	}

	if (isUserNativeFederated(user) || (await isUserInFederatedRooms(userId))) {
		throw new Meteor.Error('error-not-allowed', 'Cannot change username for federated users or users in federated rooms', {
			method: 'setUsername',
		});
	}

	if (user.username && !settings.get('Accounts_AllowUsernameChange')) {
		throw new Meteor.Error('error-not-allowed', 'Not allowed');
	}

	if (user.username === username || (user.username && user.username.toLowerCase() === username.toLowerCase())) {
		return;
	}

	if (!validateUsername(username)) {
		throw new Meteor.Error(

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Confirm you are passing the user's _id (not the username) to setUsernameWithValidation
  2. Pre-check the user exists with Users.findOneById and surface a 'user not found' state instead of letting the method throw
  3. If the id arrives from the client, re-resolve it server-side from the authenticated user (Meteor.userId()) before using it

Example fix

// before
await setUsernameWithValidation(userId, 'new.name'); // throws error-invalid-user when userId is stale

// after
const user = await Users.findOneById(userId, { projection: { _id: 1 } });
if (!user) {
  throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'setUsername' });
}
await setUsernameWithValidation(userId, 'new.name');
Defensive patterns

Strategy: validation

Validate before calling

import { Users } from '@rocket.chat/models';

const user = await Users.findOneById(userId, { projection: { _id: 1 } });
if (!user) {
  // do not call setUsernameWithValidation; refresh client state instead
}

Type guard

const isUserId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;

Try / catch

try {
  await setUsernameWithValidation(userId, username);
} catch (error) {
  if (error instanceof Meteor.Error && error.error === 'error-invalid-user') {
    // user vanished mid-flight: reload the session/user data
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: Calling the setUsername flow with an _id that was deleted, never existed, or is actually a username string passed by mistake; also a race where the account is deleted between client load and server execution.

Common situations: Stale user references in client state after account deletion; test fixtures that invoke the method without creating the user; passing user.username where user._id is expected; imported/migrated data containing dangling user ids.

Related errors


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