RocketChat/Rocket.Chat · error · Error
Invalid payload
Error message
Invalid payload
What it means
NpsModule.blockAction (appId 'nps-core') validates the interaction payload of the Net Promoter Score survey banner: container.id (viewId), triggerId, user, and payload.blockId (the NPS id) must all be present. Any of them missing aborts with a plain 'Invalid payload' error before a modal is created.
Source
Thrown at apps/meteor/server/modules/core-apps/nps.module.ts:20
import { Banner, NPS } from '@rocket.chat/core-services';
import type * as UiKit from '@rocket.chat/ui-kit';
import { createModal } from './nps/createModal';
export class Nps implements IUiKitCoreApp {
appId = 'nps-core';
async blockAction(payload: UiKitCoreAppBlockActionPayload): Promise<UiKit.ServerInteraction> {
const {
triggerId,
actionId,
container: { id: viewId } = {},
payload: { value: score, blockId: npsId },
user,
} = payload;
if (!viewId || !triggerId || !user || !npsId) {
throw new Error('Invalid payload');
}
const bannerId = viewId.replace(`${npsId}-`, '');
return createModal({
type: actionId === 'nps-score' ? 'modal.update' : 'modal.open',
id: `${npsId}-${bannerId}`,
appId: this.appId,
npsId,
triggerId,
score: String(score),
user,
});
}
async viewSubmit(payload: UiKitCoreAppViewSubmitPayload): Promise<undefined> {
if (!payload.payload?.view?.state || !payload.payload?.view?.id) {
throw new Error('Invalid payload');View on GitHub (pinned to b2c16d5842)
Solutions
- Send the interaction payload exactly as the NPS banner produced it, with container.id, triggerId, user and blockId all set
- If you build payloads programmatically, validate all four fields before dispatch
- If the NPS no longer exists, dismiss the banner client-side instead of submitting
- Log the payload at dispatch time to see which of the four fields is missing
Example fix
// before
api.call('uiKit', { appId: 'nps-core', actionId: 'nps-score', payload: { value: '10' } }); // throws 'Invalid payload'
// after
api.call('uiKit', {
appId: 'nps-core',
actionId: 'nps-score',
triggerId,
container: { id: viewId },
user,
payload: { blockId: npsId, value: '10' },
}); Defensive patterns
Strategy: validation
Validate before calling
const isNpsBlockActionValid = (p: any): boolean => Boolean(p?.container?.id && p?.triggerId && p?.user && p?.payload?.blockId);
Type guard
type NpsBlockAction = {
container: { id: string };
triggerId: string;
user: unknown;
payload: { blockId: string; value?: string };
};
const isNpsBlockAction = (p: unknown): p is NpsBlockAction =>
typeof p === 'object' && p !== null &&
typeof (p as NpsBlockAction).container?.id === 'string' &&
typeof (p as NpsBlockAction).triggerId === 'string' &&
!!(p as NpsBlockAction).user &&
typeof (p as NpsBlockAction).payload?.blockId === 'string'; Prevention
- Pass the whole interaction object from render to dispatch — never rebuild it field by field
- Add payload-shape assertions in dev builds for every UiKit dispatch
- Drop NPS banner interactions as soon as the survey is dismissed or expires locally
When it happens
Trigger: Dispatching a UiKitCoreAppBlockAction to nps-core (clicking a score in the NPS banner) where viewId, triggerId, user, or blockId is undefined — a hand-crafted payload, a client that dropped the container field, or banner state that went stale after the NPS survey was removed.
Common situations: Custom clients or bots invoking the uikit router directly with incomplete payloads; test payloads copied from another core app; survey deleted between banner render and the score click.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/20613b91968e51e3.
Report an issue: GitHub.