{"record":{"id":"d51155c22b63121a","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-d51155","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/platform/getUsersOfRoomWithoutKey.ts","lineNumber":43,"sourceCode":"\t\tprojection: { 'u._id': 1 },\n\t}).toArray();\n\tconst userIds = subscriptions.map((s) => s.u._id);\n\tconst options = { projection: { 'e2e.public_key': 1 } };\n\n\tconst users = await Users.findByIdsWithPublicE2EKey(userIds, options).toArray();\n\n\treturn {\n\t\tusers,\n\t};\n};\n\nMeteor.methods<ServerMethods>({\n\tasync 'e2e.getUsersOfRoomWithoutKey'(rid) {\n\t\tcheck(rid, String);\n\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: 'e2e.getUsersOfRoomWithoutKey',\n\t\t\t});\n\t\t}\n\n\t\tif (!rid) {\n\t\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\t\tmethod: 'e2e.getUsersOfRoomWithoutKey',\n\t\t\t});\n\t\t}\n\n\t\treturn getUsersOfRoomWithoutKeyMethod(userId, rid);\n\t},\n});\n","sourceCodeStart":25,"sourceCodeEnd":57,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/platform/getUsersOfRoomWithoutKey.ts#L25-L57","documentation":"Thrown by the 'e2e.getUsersOfRoomWithoutKey' method wrapper when the DDP connection has no authenticated user. The wrapper resolves Meteor.userId() before any room validation; a null uid aborts the E2E public-key request before room access is even evaluated.","triggerScenarios":"Running the E2E key handshake from an expired or logged-out session; calling the method during login/logout transitions; automated E2E tests without a seeded user session.","commonSituations":"Token expiry in long-lived clients during encrypted-room setup; components resuming E2E handshakes before user state loads.","solutions":["Re-authenticate and restart the E2E key exchange","Guard the call with Meteor.userId() before requesting room member keys","Sequence the handshake to start only after the user session is confirmed"],"exampleFix":"// before\nconst { users } = await Meteor.callAsync('e2e.getUsersOfRoomWithoutKey', rid);\n\n// after\nif (!Meteor.userId()) {\n  return restartE2EHandshakeAfterLogin();\n}\nconst { users } = await Meteor.callAsync('e2e.getUsersOfRoomWithoutKey', rid);","handlingStrategy":"validation","validationCode":"// client: E2E member-key requests require a session\nif (!Meteor.userId()) {\n  // defer the handshake until after login\n}","typeGuard":"import { Meteor } from 'meteor/meteor';\n\nconst isMeteorError = (err: unknown, code?: string): err is Meteor.Error =>\n  err instanceof Meteor.Error && (code === undefined || err.error === code);","tryCatchPattern":"try {\n  const { users } = await Meteor.callAsync('e2e.getUsersOfRoomWithoutKey', rid);\n} catch (err) {\n  if (isMeteorError(err, 'error-invalid-user')) {\n    // re-authenticate, then restart the key exchange\n  } else {\n    throw err;\n  }\n}","preventionTips":["Start E2E handshakes only after the user session is confirmed","Centralize session checks in the E2E flow's entry points"],"tags":["meteor","authentication","rocket-chat","e2e-encryption","rooms"],"backgroundTag":"user-not-authenticated","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}