RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
saveUser's internal findUserById throws error-invalid-user when the acting user (the id passed as the first argument, used as 'performedBy' for audit) does not exist. This fires before any validation of the payload: the caller of saveUser must be a real user record.
Source
Thrown at apps/meteor/server/lib/users/saveUser/saveUser.ts:68
joinDefaultChannels?: boolean;
sendWelcomeEmail?: boolean;
customFields?: Record<string, any>;
active?: boolean;
freeSwitchExtension?: string;
};
export type UpdateUserData = RequiredField<SaveUserData, '_id'>;
export const isUpdateUserData = (params: SaveUserData): params is UpdateUserData => '_id' in params && !!params._id;
type SaveUserOptions = {
auditStore?: UserChangedAuditStore;
};
const findUserById = async (uid: IUser['_id']): Promise<IUser> => {
const user = await Users.findOneById(uid);
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user');
}
return user;
};
const _saveUser = (session?: ClientSession) =>
async function (userId: IUser['_id'], userData: SaveUserData, options?: SaveUserOptions) {
const performedBy = await findUserById(userId);
const oldUserData = userData._id && (await Users.findOneById(userData._id));
if (oldUserData && isUserFederated(oldUserData)) {
throw new Meteor.Error('Edit_Federated_User_Not_Allowed', 'Not possible to edit a federated user');
}
await validateUserData(userId, userData);
await callbacks.run('beforeSaveUser', {
user: userData,View on GitHub (pinned to b2c16d5842)
Solutions
- Confirm the acting userId exists (Users.findOneById) before calling saveUser
- In request-driven code, take the actor from the authenticated session instead of a parameter
- In tests, seed the acting user first
Defensive patterns
Strategy: validation
Validate before calling
const actor = await Users.findOneById(actorId, { projections: { _id: 1 } });
if (!actor) throw new Error('Acting user does not exist');
await saveUser(actorId, userData); Try / catch
try {
await saveUser(actorId, userData);
} catch (e) {
if (isMeteorErrorCode(e, 'error-invalid-user')) {
// actor id is wrong/stale: re-resolve from the authenticated session
}
} Prevention
- Derive the acting user from the authenticated request, never from a free parameter
- Keep environment-specific admin ids in config, not hard-coded
When it happens
Trigger: Calling saveUser(userId, userData) with a stale, deleted, or fabricated actor id; server code invoking saveUser with a request context whose user was removed between authentication and the save.
Common situations: Automation passing a hard-coded admin id that differs per environment; the acting admin's account deleted mid-session; tests without seeded users.
Related errors
- error-user-not-found
- User not found
- error-invalid-user
- error-could-not-save-identity
- error-action-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/77783f5195225341.
Report an issue: GitHub.