RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-user
error-invalid-user
Error message
Invalid user
What it means
deleteMessageValidatingPermission (deleteMessage.ts:17-19) requires a truthy userId before performing a delete. Without a user id there is no principal to authorize, so the call fails fast with error-invalid-user 'Invalid user' - before any DB lookup happens.
Source
Thrown at apps/meteor/server/lib/messages/deleteMessage.ts:18
import { AppEvents, Apps } from '@rocket.chat/apps';
import { api, Message } from '@rocket.chat/core-services';
import { isThreadMessage, type AtLeast, type IMessage, type IRoom, type IThreadMessage, type IUser } from '@rocket.chat/core-typings';
import { Messages, Rooms, Uploads, Users, ReadReceipts, ReadReceiptsArchive, Subscriptions } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
import { settings } from '../../settings';
import { canDeleteMessageAsync } from '../authorization/canDeleteMessage';
import { callbacks } from '../callbacks';
import { FileUpload } from '../media/file-upload';
import { notifyOnRoomChangedById, notifyOnMessageChange, notifyOnSubscriptionChangedByRoomIdAndUserIds } from '../notifyListener';
export const deleteMessageValidatingPermission = async (message: AtLeast<IMessage, '_id'>, userId: IUser['_id']): Promise<void> => {
if (!message?._id) {
throw new Meteor.Error('error-invalid-message', 'Invalid message');
}
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user');
}
const user = await Users.findOneById(userId);
const originalMessage = await Messages.findOneById(message._id);
if (!originalMessage || !user || !(await canDeleteMessageAsync(user, originalMessage))) {
throw new Meteor.Error('error-action-not-allowed', 'Not allowed');
}
return deleteMessage(originalMessage, user);
};
export async function deleteMessage(message: IMessage, user: IUser): Promise<void> {
const deletedMsg: IMessage | null = await Messages.findOneById(message._id);
const isThread = (deletedMsg?.tcount || 0) > 0;
const keepHistory = settings.get('Message_KeepHistory') || isThread;
const showDeletedStatus = settings.get('Message_ShowDeletedStatus') || isThread;
View on GitHub (pinned to b2c16d5842)
Solutions
- Ensure the call runs inside an authenticated session and forward that userId (this.userId in a Meteor method)
- For server-side jobs, resolve the acting user first (e.g. the app/bot owner) and pass its _id explicitly
- Re-authenticate the client when the session expired, then retry the delete
- Guard the call site: skip deletion when userId is falsy instead of throwing
Example fix
// before deleteMessageValidatingPermission(message, undefined); // -> error-invalid-user // after const userId = this.userId ?? (await resolveBotUserId()); if (userId) await deleteMessageValidatingPermission(message, userId);
Defensive patterns
Strategy: validation
Validate before calling
if (!userId) throw new Error('Deleting requires an authenticated user');
await deleteMessageValidatingPermission(message, userId); Try / catch
try {
await deleteMessageValidatingPermission(message, userId);
} catch (error: any) {
if (error instanceof Meteor.Error && error.error === 'error-invalid-user') {
await reauthenticate(); // then retry once with a fresh session
return;
}
throw error;
} Prevention
- Bind deletions to this.userId inside Meteor methods
- Skip delete actions when the session is anonymous
- Check login state before enabling delete UI affordances
When it happens
Trigger: Invoking the deleteMessage method from an unauthenticated DDP connection; server code calling the helper with undefined userId (e.g. a background job that lost its user context); REST wrappers that drop the authenticated user when forwarding the call.
Common situations: Expired login sessions where the client still queues the delete; custom server modules calling deletion logic outside a request scope; tests that forget to stub the user; federation/app bridges that must pick a user to act as.
Related errors
- error-invalid-message
- error-action-not-allowed
- error-app-prevented-deleting
- error-invalid-room
- error-invalid-user
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/90fc9696239eb543.
Report an issue: GitHub.