RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
Thrown by 'saveUserProfile' when this.userId is null inside the method invocation: the DDP call carried no valid login token (or it expired). It is the standard logged-in guard, evaluated right after the Accounts_AllowUserProfileChange gate and before validateUserEditing permission checks.
Source
Thrown at apps/meteor/server/meteor-methods/users/saveUserProfile.ts:49
realname?: string;
newPassword?: string;
statusText?: string;
statusType?: string;
bio?: string;
nickname?: string;
},
customFields: Record<string, unknown>,
..._: unknown[]
) {
const unset: UpdateFilter<IUser> = {};
if (!rcSettings.get<boolean>('Accounts_AllowUserProfileChange')) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', {
method: 'saveUserProfile',
});
}
if (!this.userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'saveUserProfile',
});
}
await validateUserEditing(this.userId, {
_id: this.userId,
email: settings.email,
username: settings.username,
name: settings.realname,
password: settings.newPassword,
statusText: settings.statusText,
});
const user = await Users.findOneById(this.userId);
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'saveUserProfile',View on GitHub (pinned to b2c16d5842)
Solutions
- Guard submissions with Meteor.userId() and re-authenticate/redirect on null.
- Disable the form reactively when the user session ends.
- For server-to-server use, call PUT /api/v1/users.update with admin auth instead of the user-scoped DDP method.
Example fix
// before
submit = (data) => Meteor.callAsync('saveUserProfile', data, customFields);
// after
submit = (data) => {
if (!Meteor.userId()) { FlowRouter.go('/login'); return; }
Meteor.callAsync('saveUserProfile', data, customFields);
} Defensive patterns
Strategy: validation
Validate before calling
if (!Meteor.userId()) {
FlowRouter.go('/login');
} else {
await Meteor.callAsync('saveUserProfile', settings, customFields);
} Try / catch
try {
await Meteor.callAsync('saveUserProfile', settings, customFields);
} catch (e) {
if ((e as Meteor.Error).error === 'error-invalid-user') {
disableForm();
handleSessionExpired();
}
} Prevention
- Disable the profile form reactively when the session ends
- Re-login before retrying after session expiry
- Treat error-invalid-user from DDP methods as a session-expiry signal everywhere
When it happens
Trigger: Calling 'saveUserProfile' after the user logged out or the resume token expired; components surviving a session reset that still submit the profile form; DDP scripts that never logged in.
Common situations: Profile form submitted after background logout; multi-tab scenarios where one tab logs out and another submits.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/9f44b27f1704432e.
Report an issue: GitHub.