RocketChat/Rocket.Chat · error · Meteor.Error
error-action-not-allowed
error-action-not-allowed
Error message
Not allowed
What it means
The catch-all authorization failure in deleteMessageValidatingPermission (deleteMessage.ts:20-27): thrown when the original message cannot be found, the user cannot be found, or canDeleteMessageAsync returns false. That helper (authorization/canDeleteMessage.ts) denies when the room is gone/inaccessible, the user lacks force-delete-message, Message_AllowDeleting is off, the user has neither delete-message nor delete-own-message permission for the room, or the Message_AllowDeleting_BlockDeleteInMinutes window has elapsed.
Source
Thrown at apps/meteor/server/lib/messages/deleteMessage.ts:25
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;
const room = await Rooms.findOneById(message.rid, { projection: { lastMessage: 1, prid: 1, mid: 1, federated: 1, federation: 1 } });
if (deletedMsg) {
const prevent = await Apps.self?.triggerEvent(AppEvents.IPreMessageDeletePrevent, deletedMsg);
if (prevent) {
throw new Meteor.Error('error-app-prevented-deleting', 'A Rocket.Chat App prevented the message deleting.');
}View on GitHub (pinned to b2c16d5842)
Solutions
- Verify the message still exists (Messages.findOneById) before deleting - it may already be gone
- Check the acting user's room permissions: delete-own-message for own messages, delete-message for others', force-delete-message/bypass-time-limit-edit-and-delete to override limits
- Review Message_AllowDeleting and Message_AllowDeleting_BlockDeleteInMinutes settings if legit deletes fail
- Handle the race: treat 'already deleted' as success in idempotent clients
Defensive patterns
Strategy: try-catch
Try / catch
try {
await deleteMessageValidatingPermission({ _id }, userId);
} catch (error: any) {
if (error instanceof Meteor.Error && error.error === 'error-action-not-allowed') {
// check: message still exists? user has delete-message/delete-own-message?
// Message_AllowDeleting on? delete window elapsed?
showCannotDeleteMessage(_id);
return;
}
throw error;
} Prevention
- Pre-check delete-own-message/delete-message permissions in the UI before showing the delete action
- Respect Message_AllowDeleting_BlockDeleteInMinutes in client timers
- Treat repeat failures as permission drift and re-check role assignments
When it happens
Trigger: Deleting someone else's message without the room-scoped delete-message permission; Message_AllowDeleting disabled server-wide; the delete window (Message_AllowDeleting_BlockDeleteInMinutes) expired; the message id no longer exists (already deleted or wrong id); the user lost access to the room.
Common situations: Regular users trying to delete moderators' messages; tight compliance configs with a 1-minute delete window; deleting in rooms the user left or was removed from; double-delete races where the first delete already removed the message.
Related errors
- You can't delete messages because the room is readonly.
- You can't send messages because the room is readonly.
- error-action-not-allowed
- error-not-allowed
- error-action-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/6fcf2b7d6e76d66b.
Report an issue: GitHub.