RocketChat/Rocket.Chat · error · Error
error-action-not-allowed
error-action-not-allowed
Error message
error-action-not-allowed
What it means
Thrown by the guest message-edit flow (guests.ts) when `Message_AllowEditing` is false OR the original message's owner (`originalMessage.u._id`) is not the guest making the request. Guests may only edit their own messages and only while global message editing is enabled; either condition failing aborts before `updateMessageFunc` runs.
Source
Thrown at apps/meteor/server/lib/omnichannel/messages.ts:112
void callbacks.run('livechat.offlineMessage', data);
});
}
export async function updateMessage({ guest, message }: { guest: ILivechatVisitor; message: AtLeast<IMessage, '_id' | 'msg' | 'rid'> }) {
// TODO: Remove check
check(message, Match.ObjectIncluding({ _id: String }));
const originalMessage = await Messages.findOneById<Pick<IMessage, 'u' | '_id'>>(message._id, { projection: { u: 1 } });
if (!originalMessage?._id) {
return;
}
// TODO: shouldn't this happen inside updateMessageFunc?
const editAllowed = settings.get('Message_AllowEditing');
const editOwn = originalMessage.u && originalMessage.u._id === guest._id;
if (!editAllowed || !editOwn) {
throw new Error('error-action-not-allowed');
}
// TODO: Apps sends an `any` object and apparently we just check for _id being present
// while updateMessage expects AtLeast<id, msg, rid>
await updateMessageFunc(message, guest as unknown as IUser);
return true;
}
export async function deleteMessage({ guest, message }: { guest: ILivechatVisitor; message: IMessage }) {
const deleteAllowed = settings.get<boolean>('Message_AllowDeleting');
const editOwn = message.u && message.u._id === guest._id;
if (!deleteAllowed || !editOwn) {
throw new Error('error-action-not-allowed');
}
// TODO: we shouldn't do this :(View on GitHub (pinned to b2c16d5842)
Solutions
- Enable the `Message_AllowEditing` setting if guests should edit
- Hide/disable the edit action in the widget when editing is not allowed or the message is not the guest's own
- Ensure the edit call authenticates as the same guest who authored the message
Example fix
// before
await updateMessage({ guest, message: { _id: msgId, msg: 'new text' } });
// after
const original = await Messages.findOneById(msgId, { projection: { u: 1 } });
if (!settings.get('Message_AllowEditing') || original?.u?._id !== guest._id) {
throw new Error('Editing this message is not allowed');
}
await updateMessage({ guest, message: { _id: msgId, msg: 'new text' } }); Defensive patterns
Strategy: validation
Validate before calling
const original = await Messages.findOneById<Pick<IMessage, 'u'>>(message._id, { projection: { u: 1 } });
if (!settings.get('Message_AllowEditing') || original?.u?._id !== guest._id) {
throw new Error('Editing is not allowed for this message');
}
await updateMessage({ guest, message }); Type guard
const guestOwnsMessage = (guest: { _id: string }, msg: { u?: { _id?: string } }): boolean =>
msg.u?._id === guest._id; Try / catch
try {
await updateMessage({ guest, message });
} catch (e) {
if (e instanceof Error && e.message === 'error-action-not-allowed') {
// hide edit affordance; editing disabled or message not the guest's own
}
} Prevention
- Gate the widget's edit UI on Message_AllowEditing from livechat config
- Only offer edit on messages authored by the current guest
- Re-check permissions when workspace settings change at runtime
When it happens
Trigger: A livechat visitor widget calling the edit-message API after an admin disabled 'Message_AllowEditing'; or an integration editing a message on behalf of a guest who did not send it (mismatched guest._id vs message.u._id).
Common situations: Workspace policy turns off message editing and the widget's edit button was not hidden; messages edited after agent takeover where ownership metadata changed; tests replaying guest traffic with synthetic ids.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/bceef549c9650d39.
Report an issue: GitHub.