RocketChat/Rocket.Chat · warning

Integration called without room or message

Error message

Integration called without room or message

What it means

mapEventArgsToData refuses to build the webhook payload unless BOTH a room and a message object exist, for every event. In practice only sendMessage and fileUploaded attach a message in eventNameArgumentsToObject, so integrations subscribed to roomCreated, roomArchived, roomJoined, roomLeft or userCreated typically hit this guard and never receive a POST - the handler returns before mapping any data.

Source

Thrown at apps/meteor/server/lib/integrations/lib/triggerHandler.ts:268

	}

	mapEventArgsToData(data: IntegrationData, { event, message, room, owner, user }: ArgumentsObject) {
		/* The "services" field contains sensitive information such as
		the user's password hash. To prevent this information from being
		sent to the webhook, we're checking and removing it by destructuring
		the user and owner objects while discarding the "services" field.
		*/

		const omitServicesField = (object: IUser) => {
			const { services, ...objectWithoutServicesField } = object;
			return objectWithoutServicesField;
		};

		const userWithoutServicesField = user?.services ? omitServicesField(user) : user;
		const ownerWithoutServicesField = owner?.services ? omitServicesField(owner) : owner;

		if (!room || !message) {
			outgoingLogger.warn({ msg: 'Integration called without room or message', event });
			return;
		}

		switch (event) {
			case 'sendMessage':
				data.channel_id = room._id;
				data.channel_name = room.name;
				data.message_id = message._id;
				data.timestamp = message.ts;
				data.user_id = message.u._id;
				data.user_name = message.u.username;
				data.text = message.msg;
				data.siteUrl = settings.get('Site_Url');

				if (message.alias) {
					data.alias = message.alias;
				}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Use sendMessage (or fileUploaded) events for webhook integrations - these reliably carry room+message
  2. For room/user lifecycle reactions, use server-side hooks or streams instead of outgoing integrations
  3. Patch mapEventArgsToData in a fork to require room+message only for message-bearing events
  4. Confirm via the integration History: entries that never reach 'mapped-args-to-data' took this early return

Example fix

// before (server/lib/integrations/lib/triggerHandler.ts)
if (!room || !message) {
  outgoingLogger.warn({ msg: 'Integration called without room or message', event });
  return;
}

// after - only message-bearing events need a message
const MESSAGE_EVENTS = new Set(['sendMessage', 'fileUploaded']);
if (!room || (MESSAGE_EVENTS.has(event) && !message)) {
  outgoingLogger.warn({ msg: 'Integration called without room or message', event });
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

const MESSAGE_EVENTS = new Set(['sendMessage', 'fileUploaded']);
const willIntegrationFire = (event: string): boolean => MESSAGE_EVENTS.has(event);
if (!willIntegrationFire(integration.event)) {
  // pick a sendMessage-based integration or another mechanism - lifecycle events carry no message payload
}

Prevention

When it happens

Trigger: Any outgoing integration whose event carries room/user/owner but no message (all room lifecycle events and userCreated): the guard fires, mapEventArgsToData returns, and executeTriggerUrl proceeds with an empty data object - no meaningful webhook payload is delivered.

Common situations: Admins wiring outgoing webhooks to roomJoined/userCreated and seeing no deliveries; integration History showing the trigger matched but no HTTP call data; confusion because sendMessage integrations on the same server work fine.

Related errors


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