{"record":{"id":"13114107b5ec3754","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-131141","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/messages/loadHistory.ts","lineNumber":39,"sourceCode":"\t\t\tshowThreadMessages?: boolean,\n\t\t):\n\t\t\t| {\n\t\t\t\t\tmessages: IMessage[];\n\t\t\t\t\tfirstUnread: IMessage | undefined;\n\t\t\t\t\tunreadNotLoaded: number;\n\t\t\t  }\n\t\t\t| false;\n\t}\n}\n\nMeteor.methods<ServerMethods>({\n\tasync loadHistory(rid, end, limit = 20, ls, showThreadMessages = true) {\n\t\tmethodDeprecationLogger.method('loadHistory', '9.0.0', '/v1/rooms.history');\n\t\tcheck(rid, String);\n\t\tconst fromUser = await Meteor.userAsync();\n\n\t\tif (!fromUser && settings.get('Accounts_AllowAnonymousRead') === false) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', {\n\t\t\t\tmethod: 'loadHistory',\n\t\t\t});\n\t\t}\n\n\t\tconst room = await Rooms.findOneById(rid, { projection: { ...roomAccessAttributes, t: 1, sysMes: 1 } });\n\t\tif (!room) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// this checks the Allow Anonymous Read setting, so no need to check again\n\t\tif (!(await canAccessRoomAsync(room, fromUser || undefined))) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// if fromId is undefined and it passed the previous check, the user is reading anonymously\n\t\tif (!fromUser) {\n\t\t\treturn loadMessageHistory({ rid, end, limit, ls, showThreadMessages, room });\n\t\t}","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b263243745917337314259cf987c0e989cf0cdc9/apps/meteor/server/meteor-methods/messages/loadHistory.ts#L21-L57","documentation":"loadHistory is the only history method with a guest mode: it supports anonymous reads when the workspace setting Accounts_AllowAnonymousRead is enabled. It throws error-invalid-user when the caller has no user record AND Accounts_AllowAnonymousRead === false. If the setting is enabled, anonymous loads proceed to the normal room-access check, which returns false rather than throwing when access is denied.","triggerScenarios":"A logged-out visitor opening a public channel while Accounts_AllowAnonymousRead is disabled (the default); anonymous crawlers or link previews hitting a workspace where guest read was turned off; DDP clients without a login calling loadHistory.","commonSituations":"An admin disables Accounts_AllowAnonymousRead after previously allowing guests; bots scraping public channels without credentials; guest sessions continuing after the setting changed.","solutions":["Authenticate the visitor before loading history","Enable Accounts_AllowAnonymousRead (Administration → Accounts) if guest reading of public channels is intended","Catch the error and redirect anonymous visitors to the login page"],"exampleFix":"// before\nconst result = await Meteor.callAsync('loadHistory', rid, end, limit, ls);\n\n// after (client)\nconst anonReadAllowed = useSetting('Accounts_AllowAnonymousRead');\nif (!Meteor.userId() && !anonReadAllowed) {\n  showLoginPrompt();\n} else {\n  const result = await Meteor.callAsync('loadHistory', rid, end, limit, ls);\n}","handlingStrategy":"validation","validationCode":"const anonReadAllowed = publicSettings.get('Accounts_AllowAnonymousRead') ?? false;\nif (!Meteor.userId() && !anonReadAllowed) {\n  // anonymous history is disabled — send the visitor to login\n}","typeGuard":null,"tryCatchPattern":"try {\n  const history = await Meteor.callAsync('loadHistory', rid, end, limit, ls);\n} catch (error) {\n  if (error instanceof Meteor.Error && error.error === 'error-invalid-user') {\n    showLoginPrompt(); // guest read disabled and no session\n    return false;\n  }\n  throw error;\n}","preventionTips":["For guest-accessible apps, feature-detect Accounts_AllowAnonymousRead before rendering channel history","Do not assume loadHistory works anonymously — it depends on the workspace setting","Redirect anonymous visitors to login when the setting is off instead of retrying"],"tags":["authentication","anonymous-access","accounts-settings","meteor-method"],"backgroundTag":"anonymous-access-disabled","analyzedSha":"b263243745917337314259cf987c0e989cf0cdc9","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}