{"record":{"id":"38e1679152a2ad69","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-38e167","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/rooms/getRoomRoles.ts","lineNumber":22,"sourceCode":"import { Meteor } from 'meteor/meteor';\n\nimport { canAccessRoomAsync } from '../../lib/authorization';\nimport type { RoomRoles } from '../../lib/roles/getRoomRoles';\nimport { getRoomRoles } from '../../lib/roles/getRoomRoles';\nimport { settings } from '../../settings';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tgetRoomRoles(rid: IRoom['_id']): RoomRoles[];\n\t}\n}\n\nexport const executeGetRoomRoles = async (rid: IRoom['_id'], fromUser?: IUser | null) => {\n\tcheck(rid, String);\n\n\tif (!fromUser && settings.get('Accounts_AllowAnonymousRead') === false) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getRoomRoles' });\n\t}\n\n\tconst room = await Rooms.findOneById(rid);\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getRoomRoles' });\n\t}\n\n\tif (fromUser && !(await canAccessRoomAsync(room, fromUser))) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getRoomRoles' });\n\t}\n\n\treturn getRoomRoles(rid);\n};\n","sourceCodeStart":4,"sourceCodeEnd":36,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/getRoomRoles.ts#L4-L36","documentation":"executeGetRoomRoles (the shared implementation behind the getRoomRoles DDP method) rejects the call when no user context was supplied (fromUser is falsy) and the workspace setting Accounts_AllowAnonymousRead is false. Room roles are only served to identified users unless the workspace explicitly enables anonymous read access.","triggerScenarios":"Calling Meteor.call('getRoomRoles', rid) while logged out on a default workspace; invoking executeGetRoomRoles(rid) programmatically without passing the requesting user; disabling Accounts_AllowAnonymousRead while a public site still renders room content anonymously.","commonSituations":"Embedded/anonymous viewers of a workspace after the admin toggles Accounts_AllowAnonymousRead off; server code importing executeGetRoomRoles directly and forgetting the fromUser argument; guest access features tested without login.","solutions":["Pass the logged-in user: call the DDP method only when Meteor.userId() exists, or supply fromUser = await Meteor.userAsync() when invoking executeGetRoomRoles directly","Enable Administration -> General -> Accounts -> Accounts_AllowAnonymousRead if anonymous room reads are intended","Redirect anonymous users to a login flow before loading room roles"],"exampleFix":"// before - direct call without user context\nconst roles = await executeGetRoomRoles(rid);\n\n// after - pass the requesting user\nconst user = await Meteor.userAsync();\nconst roles = await executeGetRoomRoles(rid, user);","handlingStrategy":"validation","validationCode":"// pass the requesting user whenever one exists\nconst user = await Meteor.userAsync();\nif (!user && settings.get?.('Accounts_AllowAnonymousRead') === false) {\n  throw new Error('login required');\n}\nconst roles = await executeGetRoomRoles(rid, user ?? undefined);","typeGuard":null,"tryCatchPattern":"try {\n  const roles = await Meteor.callAsync('getRoomRoles', rid);\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {\n    // either anonymous on a closed workspace or (1494) access denied - recheck auth first\n    if (!Meteor.userId()) showLoginScreen();\n  }\n}","preventionTips":["Always pass fromUser when calling executeGetRoomRoles directly","Decide explicitly whether your workspace allows anonymous reads (Accounts_AllowAnonymousRead) and code accordingly","Note this method reuses 'error-invalid-user' for access denial - inspect auth state before assuming session loss"],"tags":["meteor","ddp","rooms","authentication","anonymous-read","settings"],"backgroundTag":"unauthenticated-request","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}