RocketChat/Rocket.Chat · error · Error
Invalid payload
Error message
Invalid payload
What it means
`retrieveMentionsFromPayload` in the `mention-core` UiKit core app parses the block action's `value` (a JSON-stringified mentions array). After a successful `JSON.parse`, it validates the result: it must be a non-empty array whose first element has a `username` property. Failing that shape check throws `Error('Invalid payload')` at this line.
Source
Thrown at apps/meteor/server/modules/core-apps/mention.module.ts:16
import { api } from '@rocket.chat/core-services';
import type { IUiKitCoreApp, UiKitCoreAppBlockActionPayload } from '@rocket.chat/core-services';
import type { IMessage, IUser } from '@rocket.chat/core-typings';
import { Subscriptions, Messages } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
import { i18n } from '../../lib/i18n';
import { processWebhookMessage } from '../../lib/messages/processWebhookMessage';
import { roomCoordinator } from '../../lib/rooms/roomCoordinator';
import { addUsersToRoomMethod } from '../../meteor-methods/rooms/addUsersToRoom';
const retrieveMentionsFromPayload = (stringifiedMentions: string): Exclude<IMessage['mentions'], undefined> => {
try {
const mentions = JSON.parse(stringifiedMentions);
if (!Array.isArray(mentions) || !mentions.length || !('username' in mentions[0])) {
throw new Error('Invalid payload');
}
return mentions;
} catch (error) {
throw new Error('Invalid payload');
}
};
export class MentionModule implements IUiKitCoreApp {
appId = 'mention-core';
async blockAction(payload: UiKitCoreAppBlockActionPayload): Promise<undefined> {
const {
actionId,
payload: { value: stringifiedMentions, blockId: referenceMessageId },
} = payload;
const user = payload.user!;
const room = payload.room!;View on GitHub (pinned to b2c16d5842)
Solutions
- Send the value as `JSON.stringify(mentions)` where mentions is `[{ username: 'user1' }, ...]` — non-empty, each entry with a `username` field.
- Check the raw `value` string before dispatch to confirm it parses to the expected array-of-username-objects shape.
- If you build the ephemeral mention prompt yourself, reuse the same serialization as the core mention bot.
Example fix
// before
value: JSON.stringify(['user1', 'user2'])
// after
value: JSON.stringify([{ username: 'user1' }, { username: 'user2' }]) Defensive patterns
Strategy: validation
Validate before calling
const isMentionArray = (value: unknown): value is { username: string }[] =>
Array.isArray(value) && value.length > 0 && value.every((m) => typeof m === 'object' && m !== null && 'username' in m);
const parsed = JSON.parse(stringifiedMentions);
if (!isMentionArray(parsed)) {
throw new Error('Mentions value must be a non-empty array of { username } objects');
}
// safe to dispatch Type guard
type Mention = { username: string };
function isMentionArray(value: unknown): value is Mention[] {
return (
Array.isArray(value) &&
value.length > 0 &&
value.every((m) => typeof m === 'object' && m !== null && typeof (m as Mention).username === 'string')
);
} Try / catch
try {
await mentionModule.blockAction(payload);
} catch (error) {
if (error instanceof Error && error.message === 'Invalid payload') {
// log payload.payload.value to inspect the malformed mentions JSON
}
} Prevention
- Serialize mentions with JSON.stringify([{ username }])
- Validate the parsed shape before dispatch
- Add unit tests for the mention value format
When it happens
Trigger: A mention-core blockAction where `payload.value` parses as JSON but is not a mentions array — e.g. `["user1"]` (strings instead of objects), `[]` (empty), `{}` (not an array), or objects lacking `username` like `[{ _id: 'x' }]`.
Common situations: Custom clients building the mention prompt value by hand; payload shapes changed between versions; double-stringified or truncated JSON that happens to parse to a non-array value.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/be94cc82fc249b5a.
Report an issue: GitHub.