RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
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).
Source
Thrown at apps/meteor/server/meteor-methods/messages/getUserMentionsByChannel.ts:26
import { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
getUserMentionsByChannel(params: { roomId: string; options: { limit: number; skip: number; sort: { ts: -1 | 1 } } }): IMessage[];
}
}
export const getUserMentionsByChannel = async (
userId: string,
roomId: string,
options: { limit?: number; skip?: number; sort?: { ts?: -1 | 1 } },
) => {
check(roomId, String);
const user = await Users.findOneById(userId);
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user');
}
const room = await Rooms.findOneById(roomId);
if (!room || !(await canAccessRoomAsync(room, user))) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
method: 'getUserMentionsByChannel',
});
}
return Messages.findVisibleByMentionAndRoomId(user.username, roomId, options).toArray();
};
Meteor.methods<ServerMethods>({
async getUserMentionsByChannel({ roomId, options }) {
methodDeprecationLogger.method('getUserMentionsByChannel', '9.0.0', '/v1/channels.getAllUserMentionsByChannel');
const uid = Meteor.userId();
View on GitHub (pinned to b2c16d5842)
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
Example fix
// before
const mentions = await getUserMentionsByChannel(userId, roomId, options);
// after
const user = await Users.findOneById(userId);
if (!user) {
throw new Error('stale session — re-login required');
}
const mentions = await getUserMentionsByChannel(userId, roomId, options); Defensive patterns
Strategy: validation
Validate before calling
const currentUserId = Meteor.userId();
const userStillExists = currentUserId && UsersCollection.findOne({ _id: currentUserId });
if (!userStillExists) {
// stale session for a deleted user — force logout instead of calling
} Try / catch
try {
const mentions = await Meteor.callAsync('getUserMentionsByChannel', { roomId, options });
} catch (error) {
if (error instanceof Meteor.Error && error.error === 'error-invalid-user') {
// user record gone — logout and clear local state
} else {
throw error;
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/6788f0de4fe3e81e.
Report an issue: GitHub.