{"record":{"id":"834ef7e473423f1a","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-834ef7","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/joinRoom.ts","lineNumber":24,"sourceCode":"import { Meteor } from 'meteor/meteor';\n\nimport { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tjoinRoom(rid: IRoom['_id'], code?: string): boolean | undefined;\n\t}\n}\n\nMeteor.methods<ServerMethods>({\n\tasync joinRoom(rid, code) {\n\t\tmethodDeprecationLogger.method('joinRoom', '9.0.0', '/v1/rooms.join');\n\t\tcheck(rid, String);\n\n\t\tconst user = await Meteor.userAsync();\n\t\tif (!user) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'joinRoom' });\n\t\t}\n\n\t\tconst room = await Rooms.findOneById(rid);\n\t\tif (!room) {\n\t\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'joinRoom' });\n\t\t}\n\n\t\treturn Room.join({ room, user, ...(code ? { joinCode: code } : {}) });\n\t},\n});\n","sourceCodeStart":6,"sourceCodeEnd":35,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/joinRoom.ts#L6-L35","documentation":"Thrown by the deprecated joinRoom Meteor method when Meteor.userAsync() resolves to null - no logged-in user on the connection. The method (deprecated in favor of /v1/rooms.join) needs an authenticated user to join the room, and check(rid, String) has already passed, so the failure is purely the missing session.","triggerScenarios":"Meteor.call('joinRoom', rid, code) fired before login completes, after logout, or with an expired resume token; deep-link handlers (/invite/<rid>) that auto-join before the session is restored.","commonSituations":"Invite links opened by logged-out users where the join fires immediately; tab left open across a session expiry; server-side scripts invoking the DDP method without a user.","solutions":["Require login before attempting the join; queue the join and execute it in Accounts.onLogin","Re-authenticate when the resume token expired","Migrate to POST /api/v1/rooms.join with { roomId, joinCode } and API credentials"],"exampleFix":"// before (deprecated + auth-gated)\nawait Meteor.callAsync('joinRoom', rid, code);\n\n// after - REST endpoint after login\nawait fetch('/api/v1/rooms.join', {\n  method: 'POST',\n  headers: { 'X-Auth-Token': token, 'X-User-Id': uid },\n  body: JSON.stringify({ roomId: rid, joinCode: code }),\n});","handlingStrategy":"validation","validationCode":"if (!Meteor.userId()) {\n  // invite links: park the target room and complete the join after login\n  throw new Error('login required');\n}\nawait Meteor.callAsync('joinRoom', rid, code);","typeGuard":null,"tryCatchPattern":"try {\n  const joined = await Meteor.callAsync('joinRoom', rid, code);\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {\n    pendingJoin = { rid, code }; // retry once after Accounts.onLogin\n    showLoginScreen();\n  } else if (e instanceof Meteor.Error && e.error === 'error-invalid-room') {\n    notifyRoomDeleted();\n  }\n}","preventionTips":["Migrate to POST /v1/rooms.join - the DDP method is removed in 9.0.0","On invite-link flows, always complete login before issuing the join call","Handle 'error-invalid-room' separately - a valid session cannot join a deleted room"],"tags":["meteor","ddp","authentication","rooms","join","deprecated"],"backgroundTag":"unauthenticated-request","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}