RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
checkUsernameAvailabilityWithValidation throws error-invalid-user (method 'setUsername') when Users.findOneById(userId) returns null: the session/acting user no longer exists in the database. The user record was deleted or the id is bogus, so availability cannot be validated on their behalf.
Source
Thrown at apps/meteor/server/lib/users/checkUsernameAvailability.ts:31
const toRegExp = (username: string): RegExp => new RegExp(`^${escapeRegExp(username).trim()}$`, 'i');
settings.watch('Accounts_BlockedUsernameList', (value: string) => {
usernameBlackList = ['all', 'here'].concat(value.split(',')).map(toRegExp);
});
const usernameIsBlocked = (username: string, usernameBlackList: RegExp[]): boolean | number =>
usernameBlackList.length && usernameBlackList.some((restrictedUsername) => restrictedUsername.test(escapeRegExp(username).trim()));
export const checkUsernameAvailabilityWithValidation = async function (userId: string, username: string): Promise<boolean> {
if (!username) {
throw new Meteor.Error('error-invalid-username', 'Invalid username', { method: 'setUsername' });
}
const user = await Users.findOneById(userId, { projection: { username: 1 } });
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'setUsername' });
}
if (user.username && !settings.get('Accounts_AllowUsernameChange')) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'setUsername' });
}
if (user.username === username) {
return true;
}
return checkUsernameAvailability(username);
};
export const checkUsernameAvailability = async function (username: string, type: UsernameAvailabilityCheckType = 'user'): Promise<boolean> {
if (usernameIsBlocked(username, usernameBlackList) || !validateName(username)) {
throw new Meteor.Error('error-blocked-username', `${_.escape(username)} is blocked and can't be used!`, {
method: 'checkUsernameAvailability',
field: username,
});View on GitHub (pinned to b2c16d5842)
Solutions
- Verify the user exists (Users.findOneById or GET /api/v1/users.info) before initiating the username flow
- If this fires for a live session, log the user out: their account is gone and every subsequent call will fail
- In tests, seed the user record before invoking setUsername
Defensive patterns
Strategy: try-catch
Validate before calling
const me = await Users.findOneById(userId, { projections: { _id: 1 } });
if (!me) throw new Error('Session user no longer exists');
await checkUsernameAvailabilityWithValidation(userId, username); Type guard
const isMeteorErrorCode = (e: unknown, code: string): e is { error: string; reason?: string } =>
typeof e === 'object' && e !== null && (e as { error?: unknown }).error === code; Try / catch
try {
await checkUsernameAvailabilityWithValidation(userId, username);
} catch (e) {
if (isMeteorErrorCode(e, 'error-invalid-user')) {
forceLogout(); // account deleted, session is dead
}
} Prevention
- Handle account-deleted sessions globally (401/invalid-user) with a logout redirect
- Seed acting users in tests before calling user-scoped methods
When it happens
Trigger: A logged-in user's account is deleted while their session is still active and they attempt to set a username; server-side code calling the validation with a made-up or stale user id.
Common situations: Admin deletes a user whose browser tab remains open; token reuse after account removal; test code passing hard-coded ids that do not exist in the current database.
Related errors
- User not found
- Invalid user
- User must have a username to be banned from the room
- error-invalid-username
- error-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/a3db67050f404743.
Report an issue: GitHub.