{"record":{"id":"393c0e3c15db32bb","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-393c0e","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/getRoomById.ts","lineNumber":22,"sourceCode":"import { check } from 'meteor/check';\nimport { DDPRateLimiter } from 'meteor/ddp-rate-limiter';\nimport { Meteor } from 'meteor/meteor';\n\nimport { canAccessRoomAsync } from '../../lib/authorization';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tgetRoomById(rid: IRoom['_id']): IRoom;\n\t}\n}\n\nMeteor.methods<ServerMethods>({\n\tasync getRoomById(rid) {\n\t\tcheck(rid, String);\n\t\tconst userId = Meteor.userId();\n\t\tif (!userId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', {\n\t\t\t\tmethod: 'getRoomNameById',\n\t\t\t});\n\t\t}\n\n\t\tconst room = await Rooms.findOneById(rid);\n\t\tif (room == null) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', {\n\t\t\t\tmethod: 'getRoomNameById',\n\t\t\t});\n\t\t}\n\t\tif (!(await canAccessRoomAsync(room, (await Meteor.userAsync()) as IUser))) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', {\n\t\t\t\tmethod: 'getRoomById',\n\t\t\t});\n\t\t}\n\t\treturn room;\n\t},\n});","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/getRoomById.ts#L4-L40","documentation":"Thrown by the getRoomById Meteor method when the DDP connection has no authenticated user (Meteor.userId() is null). Note the error details carry method: 'getRoomNameById' - a copy-paste artifact in the source - so do not rely on details.method to identify which call failed; match on the error code 'error-invalid-user' instead.","triggerScenarios":"Calling Meteor.call('getRoomById', rid) from an anonymous connection: the client never logged in, logged out, or its resume token expired and was purged, so Meteor.userId() returns null before check(rid, String) even matters.","commonSituations":"Client calls a room method before Accounts login completes; session expired after long idle; logout race where a reactive autorun fires the call after logout; server-side integration code invoking the method without a userId bound to the connection.","solutions":["Guard the call site: only invoke getRoomById when Meteor.userId() is truthy","Re-authenticate if the token expired (password login or SSO) to establish a new session","Audit reactive autoruns that call room methods and make them conditional on Meteor.userId()","For machine-to-machine use, call the REST equivalent GET /api/v1/rooms.info with an auth token instead of an anonymous DDP call"],"exampleFix":"// before\nconst room = await Meteor.callAsync('getRoomById', rid);\n\n// after\nif (!Meteor.userId()) throw new Error('login required');\nconst room = await Meteor.callAsync('getRoomById', rid);","handlingStrategy":"validation","validationCode":"// client: gate the call on an established session\nif (!Meteor.userId()) {\n  throw new Error('login required');\n}\nconst room = await Meteor.callAsync('getRoomById', rid);","typeGuard":null,"tryCatchPattern":"try {\n  const room = await Meteor.callAsync('getRoomById', rid);\n} catch (e) {\n  // details.method is 'getRoomNameById' here (source bug) - match on the code only\n  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {\n    showLoginScreen();\n  }\n}","preventionTips":["Do not branch on err.details.method for this method - the source labels it 'getRoomNameById'","Make reactive room lookups conditional on Meteor.userId() in autoruns","Use REST /v1/rooms.info with token auth for integrations instead of anonymous DDP calls"],"tags":["meteor","ddp","authentication","rooms"],"backgroundTag":"unauthenticated-request","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}