{"record":{"id":"6788f0de4fe3e81e","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-6788f0","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/getUserMentionsByChannel.ts","lineNumber":26,"sourceCode":"import { 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\tgetUserMentionsByChannel(params: { roomId: string; options: { limit: number; skip: number; sort: { ts: -1 | 1 } } }): IMessage[];\n\t}\n}\n\nexport const getUserMentionsByChannel = async (\n\tuserId: string,\n\troomId: string,\n\toptions: { limit?: number; skip?: number; sort?: { ts?: -1 | 1 } },\n) => {\n\tcheck(roomId, String);\n\n\tconst user = await Users.findOneById(userId);\n\tif (!user) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user');\n\t}\n\n\tconst room = await Rooms.findOneById(roomId);\n\n\tif (!room || !(await canAccessRoomAsync(room, user))) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\tmethod: 'getUserMentionsByChannel',\n\t\t});\n\t}\n\n\treturn Messages.findVisibleByMentionAndRoomId(user.username, roomId, options).toArray();\n};\n\nMeteor.methods<ServerMethods>({\n\tasync getUserMentionsByChannel({ roomId, options }) {\n\t\tmethodDeprecationLogger.method('getUserMentionsByChannel', '9.0.0', '/v1/channels.getAllUserMentionsByChannel');\n\t\tconst uid = Meteor.userId();\n","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/messages/getUserMentionsByChannel.ts#L8-L44","documentation":"The exported getUserMentionsByChannel(userId, roomId, options) helper throws error-invalid-user when Users.findOneById(userId) returns null — the passed userId matches no user document. Reached through the Meteor method wrapper, userId is always the logged-in user's id, so in practice this means the session belongs to a user record that no longer exists (deleted or merged mid-session).","triggerScenarios":"Calling the exported helper directly with a stale or deleted userId; the user document being deleted while their session is still live (admin deletion, purge); a race where Meteor.userId() resolved but the user record was removed before the lookup.","commonSituations":"An admin deletes a user whose browser tab is still open; imports/merges that rewrite user ids; test code invoking the helper with hardcoded ids from a previous database state.","solutions":["Verify the user id exists (or trust the session and treat the error as 'stale session')","Force re-login by clearing the resume token so the stale session is discarded","Tear down client state for deleted users instead of retrying"],"exampleFix":"// before\nconst mentions = await getUserMentionsByChannel(userId, roomId, options);\n\n// after\nconst user = await Users.findOneById(userId);\nif (!user) {\n  throw new Error('stale session — re-login required');\n}\nconst mentions = await getUserMentionsByChannel(userId, roomId, options);","handlingStrategy":"validation","validationCode":"const currentUserId = Meteor.userId();\nconst userStillExists = currentUserId && UsersCollection.findOne({ _id: currentUserId });\nif (!userStillExists) {\n  // stale session for a deleted user — force logout instead of calling\n}","typeGuard":null,"tryCatchPattern":"try {\n  const mentions = await Meteor.callAsync('getUserMentionsByChannel', { roomId, options });\n} catch (error) {\n  if (error instanceof Meteor.Error && error.error === 'error-invalid-user') {\n    // user record gone — logout and clear local state\n  } else {\n    throw error;\n  }\n}","preventionTips":["Handle account-deleted events by destroying the session","When calling the exported helper server-side, pass ids fetched from the database in the same request, not cached values","Avoid hardcoding user ids in tests against a changing database"],"tags":["user","mentions","meteor-method","session"],"backgroundTag":"user-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}