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

  1. Gate every save on a live Meteor.userId() and re-login or redirect when it is null.
  2. Cancel pending autosave timers on logout (cleanup in useEffect / onDestroy).
  3. 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

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.