RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
Authentication guard of the 'saveUserPreferences' Meteor method: Meteor.userId() is null, so the call had no valid login token. Preferences are strictly per-user, so an anonymous invocation is rejected before any settings are read. The method is deprecated since 9.0.0 in favor of POST /v1/users.setPreferences.
Source
Thrown at apps/meteor/server/meteor-methods/users/saveUserPreferences.ts:254
if (language && oldLanguage !== language && rcSettings.get('AutoTranslate_AutoEnableOnJoinRoom')) {
const workspaceLanguage = rcSettings.get('Language');
const targetLanguage = language === 'default' || language === workspaceLanguage ? null : language;
const response = await Subscriptions.setAutoTranslateByUserId(user._id, targetLanguage);
if (response.modifiedCount) {
void notifyOnSubscriptionChangedByAutoTranslateAndUserId(user._id);
}
}
});
};
Meteor.methods<ServerMethods>({
async saveUserPreferences(settings) {
methodDeprecationLogger.method('saveUserPreferences', '9.0.0', '/v1/users.setPreferences');
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'saveUserPreferences' });
}
await saveUserPreferences(settings, userId);
return true;
},
});
View on GitHub (pinned to 2a7de45707)
Solutions
- Gate every save on a live Meteor.userId() and re-login or redirect when it is null.
- Cancel pending autosave timers on logout (cleanup in useEffect / onDestroy).
- Move integrations to POST /v1/users.setPreferences with a valid auth token.
Example fix
// before (autosave fires regardless of session)
const save = debounce((prefs) => Meteor.callAsync('saveUserPreferences', prefs), 500);
// after
timer && Tracker.autorun(() => {
if (!Meteor.userId()) save.cancel();
});
const save = debounce((prefs) => {
if (!Meteor.userId()) return;
Meteor.callAsync('saveUserPreferences', prefs);
}, 500); Defensive patterns
Strategy: validation
Validate before calling
if (!Meteor.userId()) {
FlowRouter.go('/login');
} else {
await Meteor.callAsync('saveUserPreferences', prefs);
} Try / catch
try {
await Meteor.callAsync('saveUserPreferences', prefs);
} catch (e) {
if ((e as Meteor.Error).error === 'error-invalid-user') {
cancelPendingAutosaves();
handleSessionExpired();
}
} Prevention
- Cancel debounced autosave timers on logout
- Re-check Meteor.userId() at save time, not just at page load
- Use POST /v1/users.setPreferences for integrations with token refresh
When it happens
Trigger: Meteor.call('saveUserPreferences', prefs) after logout/token expiry; scripts calling the method on a DDP connection without logging in; preference autosave firing during the logout transition.
Common situations: Long-open preference pages with debounced autosave that fires after session death; load-test harnesses skipping authentication.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@2a7de45707 (2026-08-18).
Data as JSON: /api/errors/290633bee7b24e0f.
Report an issue: GitHub.