{"record":{"id":"290633bee7b24e0f","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-290633","errorCode":"error-invalid-user","errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/users/saveUserPreferences.ts","lineNumber":254,"sourceCode":"\n\t\tif (language && oldLanguage !== language && rcSettings.get('AutoTranslate_AutoEnableOnJoinRoom')) {\n\t\t\tconst workspaceLanguage = rcSettings.get('Language');\n\t\t\tconst targetLanguage = language === 'default' || language === workspaceLanguage ? null : language;\n\n\t\t\tconst response = await Subscriptions.setAutoTranslateByUserId(user._id, targetLanguage);\n\t\t\tif (response.modifiedCount) {\n\t\t\t\tvoid notifyOnSubscriptionChangedByAutoTranslateAndUserId(user._id);\n\t\t\t}\n\t\t}\n\t});\n};\n\nMeteor.methods<ServerMethods>({\n\tasync saveUserPreferences(settings) {\n\t\tmethodDeprecationLogger.method('saveUserPreferences', '9.0.0', '/v1/users.setPreferences');\n\t\tconst userId = Meteor.userId();\n\t\tif (!userId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'saveUserPreferences' });\n\t\t}\n\n\t\tawait saveUserPreferences(settings, userId);\n\n\t\treturn true;\n\t},\n});\n","sourceCodeStart":236,"sourceCodeEnd":262,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2a7de457074cbb4d4373fbd9a4e5bea292c9c764/apps/meteor/server/meteor-methods/users/saveUserPreferences.ts#L236-L262","documentation":"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.","triggerScenarios":"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.","commonSituations":"Long-open preference pages with debounced autosave that fires after session death; load-test harnesses skipping authentication.","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."],"exampleFix":"// before (autosave fires regardless of session)\nconst save = debounce((prefs) => Meteor.callAsync('saveUserPreferences', prefs), 500);\n\n// after\ntimer && Tracker.autorun(() => {\n  if (!Meteor.userId()) save.cancel();\n});\nconst save = debounce((prefs) => {\n  if (!Meteor.userId()) return;\n  Meteor.callAsync('saveUserPreferences', prefs);\n}, 500);","handlingStrategy":"validation","validationCode":"if (!Meteor.userId()) {\n  FlowRouter.go('/login');\n} else {\n  await Meteor.callAsync('saveUserPreferences', prefs);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await Meteor.callAsync('saveUserPreferences', prefs);\n} catch (e) {\n  if ((e as Meteor.Error).error === 'error-invalid-user') {\n    cancelPendingAutosaves();\n    handleSessionExpired();\n  }\n}","preventionTips":["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"],"tags":["authentication","session-expired","preferences","meteor-method"],"backgroundTag":"user-not-authenticated","analyzedSha":"2a7de457074cbb4d4373fbd9a4e5bea292c9c764","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}