RocketChat/Rocket.Chat · error · Error

invalid triggerId

Error message

invalid triggerId

What it means

`CloudSubscriptionCommunication.viewClosed` throws `Error('invalid triggerId')` when `payload.triggerId` is falsy. The triggerId addresses the `modal.close` response back to the client surface and is forwarded to Cloud, so a close without it is rejected before `handlePayload` runs.

Source

Thrown at apps/meteor/server/modules/core-apps/cloudSubscriptionCommunication.module.ts:24

export class CloudSubscriptionCommunication extends CloudAnnouncementsModule {
	override appId = 'cloud-communication-core';

	override async viewClosed(payload: UiKitCoreAppViewClosedPayload): Promise<UiKit.ServerInteraction> {
		const {
			payload: { view: { viewId } = {} },
			user: { _id: userId } = {},
		} = payload;

		if (!userId) {
			throw new Error('invalid user');
		}

		if (!viewId) {
			throw new Error('invalid view');
		}

		if (!payload.triggerId) {
			throw new Error('invalid triggerId');
		}

		// for viewClosed we just need to let Cloud know that the banner was closed, no need to wait for the response

		void this.handlePayload(payload);

		return {
			type: 'modal.close',
			triggerId: payload.triggerId,
			appId: payload.appId,
		};
	}
}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Forward the `triggerId` from the surface that opened the modal in the close payload.
  2. If no response surface exists, use the underlying service call directly instead of the UiKit module.

Example fix

// before
await cloudCommunicationModule.viewClosed({ appId: 'cloud-communication-core', user: { _id: userId }, payload: { view: { viewId } } } as any);

// after
await cloudCommunicationModule.viewClosed({ appId: 'cloud-communication-core', user: { _id: userId }, payload: { view: { viewId } }, triggerId } as any);
Defensive patterns

Strategy: validation

Validate before calling

if (!payload.triggerId) {
  throw new Error('triggerId is required to close cloud communication modals');
}
await cloudCommunicationModule.viewClosed(payload);

Type guard

const hasCloseTrigger = (
  payload: UiKitCoreAppViewClosedPayload,
): payload is UiKitCoreAppViewClosedPayload & { triggerId: string } =>
  typeof payload.triggerId === 'string' && payload.triggerId.length > 0;

Try / catch

try {
  await cloudCommunicationModule.viewClosed(payload);
} catch (error) {
  if (error instanceof Error && error.message === 'invalid triggerId') {
    // dismiss via the underlying service without a modal.close response
  }
}

Prevention

When it happens

Trigger: Closing a cloud communication modal through a viewClosed interaction that lacks `triggerId` — manually built payloads, replayed events, or clients that do not propagate the trigger.

Common situations: Custom automation mimicking modal close; tests omitting trigger metadata; middleware stripping fields.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/5bc2703ef4e20b18. Report an issue: GitHub.