RocketChat/Rocket.Chat · error · PinMessagesNotAllowed
error-pinning-message
error-pinning-message
Error message
Error pinning message
What it means
updatePinMessage() is the optimistic-update hook for the pinMessage mutation: it throws PinMessagesNotAllowed('Error pinning message', { method: 'pinMessage' }) — error code error-pinning-message — when Messages.state.get(message._id) is undefined, i.e. the message being pinned is not in the local store and there is nothing to optimistically mark as pinned.
Solutions
- Ensure the message is stored (Messages.state.store(message)) before dispatching the pin mutation.
- Catch PinMessagesNotAllowed specifically and re-fetch/refresh instead of leaving the UI stuck.
- Route pin actions through the normal room data layer so the message is always cached.
Example fix
// before
updatePinMessage(message, { pinned: true }); // throws if not in store
// after
if (!Messages.state.get(message._id)) {
Messages.state.store(message); // hydrate before optimistic update
}
updatePinMessage(message, { pinned: true }); Defensive patterns
Strategy: try-catch
Validate before calling
if (!Messages.state.get(message._id)) {
Messages.state.store(message); // hydrate before the optimistic update
}
updatePinMessage(message, { pinned: true }); Type guard
const isMessageCached = (message: IMessage): boolean => Boolean(Messages.state.get(message._id));
Try / catch
import { PinMessagesNotAllowed } from '../../../lib/errors/PinMessagesNotAllowed';
try {
updatePinMessage(message, { pinned: true });
} catch (e) {
if (e instanceof PinMessagesNotAllowed) {
dispatchToastMessage({ type: 'error', message: t('error-pinning-message') });
return;
}
throw e;
} Prevention
- Route pin actions through surfaces whose messages are already in Messages.state.
- Store the message before dispatching the pinMessage mutation.
- Catch PinMessagesNotAllowed explicitly and refresh rather than leaving toggled UI.
When it happens
Trigger: The pinMessage mutation firing for a message that was never stored in Messages.state (pinned from a surface that fetched the message via REST without hydrating the store) or that was evicted/removed from the cache before the mutation ran.
Common situations: Pin actions in search results, pinned-messages lists, or notification contexts that bypass the room message cache; cache clears mid-session; double mutations after message deletion.
Related errors
- error-action-not-allowed
- error-action-not-allowed
- error-app-prevented-deleting
- error-invalid-actionlink
- error-invalid-message
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/36739c10dc4b05ec.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/client/lib/mutationEffects/updatePinMessage.ts:10
import type { IMessage } from '@rocket.chat/core-typings';
import { Messages } from '../../stores';
import { PinMessagesNotAllowed } from '../errors/PinMessagesNotAllowed';
export const updatePinMessage = (message: IMessage, data: Partial<IMessage>) => {
const msg = Messages.state.get(message._id);
if (!msg) {
throw new PinMessagesNotAllowed('Error pinning message', {
method: 'pinMessage',
});
}
Messages.state.update(
(record) => record._id === message._id && record.rid === message.rid,
(record) => ({ ...record, ...data }),
);
};
View on GitHub (pinned to b2c16d5842)