RocketChat/Rocket.Chat · error · Error
invalid-user
Error message
invalid-user
What it means
Inside findMentionedMessages (chat.getMentionedMessages flow), after room access passes, the helper loads the authenticated user by uid with a username projection to search for mentions of that username. If no user document exists for the uid on the request (Users.findOneById returns null) it throws plain Error 'invalid-user'. In practice this only happens when the auth token references a user that has since been deleted or the token is corrupt yet passed authentication.
Source
Thrown at apps/meteor/server/api/lib/messages.ts:27
roomId,
pagination: { offset, count, sort },
}: {
uid: string;
roomId: string;
pagination: { offset: number; count: number; sort: FindOptions<IMessage>['sort'] };
}): Promise<{
messages: IMessage[];
count: number;
offset: number;
total: number;
}> {
const room = await Rooms.findOneById(roomId);
if (!room || !(await canAccessRoomAsync(room, { _id: uid }))) {
throw new Error('error-not-allowed');
}
const user = await Users.findOneById<Pick<IUser, 'username'>>(uid, { projection: { username: 1 } });
if (!user) {
throw new Error('invalid-user');
}
const { cursor, totalCount } = Messages.findPaginatedVisibleByMentionAndRoomId(user.username, roomId, {
sort: sort || { ts: -1 },
skip: offset,
limit: count,
});
const [messages, total] = await Promise.all([cursor.toArray(), totalCount]);
return {
messages,
count: messages.length,
offset,
total,
};
}
View on GitHub (pinned to b2c16d5842)
Solutions
- Re-authenticate: obtain a fresh token for a user that exists (check with GET /api/v1/me)
- If the account was deleted, recreate it or switch the integration to a service account
- For flaky occurrences, inspect whether a concurrent deletion is running
Example fix
// before
GET /api/v1/chat.getMentionedMessages (X-Auth-Token of deleted user) -> invalid-user
// after
POST /api/v1/login { "user": "live.bot", "password": "..." } // fresh token, then retry Defensive patterns
Strategy: try-catch
Validate before calling
async function assertTokenAlive(client) {
const me = await client.get('/api/v1/me');
if (me.status === 401) throw new Error('token stale — re-authenticate');
} Try / catch
try {
await client.get('/api/v1/chat.getMentionedMessages', { params: { roomId } });
} catch (e: any) {
if ((e?.response?.data?.error ?? '') === 'invalid-user') {
// authed uid no longer exists: drop cached token, re-login once, then retry
await invalidateTokenAndReauth();
}
throw e;
} Prevention
- Rotate long-lived tokens for service accounts rather than keeping them forever
- Invalidate stored credentials whenever /api/v1/me returns 401
- Avoid issuing tokens for users slated for deletion
When it happens
Trigger: Calling chat.getMentionedMessages with a token for a user deleted between token issuance and this request, or a hand-crafted/expired session whose userId no longer resolves.
Common situations: Long-lived bot/personal access token kept after the account was removed; user deleted mid-session while a client retried; workspace data restored from a backup that lacks the user row.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/d24b1265ff13378f.
Report an issue: GitHub.