RocketChat/Rocket.Chat · warning

Unhandled trigger event

Error message

Unhandled trigger event

What it means

executeTriggers maps emitted event names to argument objects through a fixed switch covering exactly sendMessage, fileUploaded, roomArchived, roomCreated, roomJoined, roomLeft and userCreated. Any other event name hits the default branch: warn, event set to undefined, and executeTriggers returns immediately - no integrations run for that emission.

Source

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

			case 'roomJoined':
				if (args.length >= 3) {
					argObject.user = args[1] as IUser;
					argObject.room = args[2] as IRoom;
				}
				break;
			case 'roomLeft':
				if (args.length >= 3) {
					argObject.user = (args[1] as { user: IUser })?.user;
					argObject.room = args[2] as IRoom;
				}
				break;
			case 'userCreated':
				if (args.length >= 2) {
					argObject.user = args[1] as IUser;
				}
				break;
			default:
				outgoingLogger.warn({ msg: 'Unhandled trigger event', event: argObject.event });
				argObject.event = undefined;
				break;
		}

		outgoingLogger.debug({
			msg: 'Got the event arguments for the event',
			event: argObject.event,
			messageId: argObject.message?._id,
			roomId: argObject.room?._id,
			userId: argObject.user?._id || argObject.owner?._id,
		});

		return argObject;
	}

	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

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Use one of the seven supported event names, exactly spelled and case-sensitive
  2. If a custom event is required, extend eventNameArgumentsToObject's switch in your fork
  3. Cross-check what each event supports against outgoingEvents (app/integrations/lib/outgoingEvents.ts)
  4. Look for the paired 'Execute Trigger:' debug line to see the raw first argument actually received
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED_EVENTS = new Set(['sendMessage', 'fileUploaded', 'roomArchived', 'roomCreated', 'roomJoined', 'roomLeft', 'userCreated']);
if (!SUPPORTED_EVENTS.has(eventName)) {
  logger.warn({ msg: 'refusing to emit unsupported integration event', eventName });
}

Type guard

const isSupportedOutgoingEvent = (
  e: unknown,
): e is 'sendMessage' | 'fileUploaded' | 'roomArchived' | 'roomCreated' | 'roomJoined' | 'roomLeft' | 'userCreated' =>
  typeof e === 'string' && SUPPORTED_EVENTS.has(e);

Prevention

When it happens

Trigger: Custom server code calling the integration handler's executeTriggers with a new or misspelled event name ('RoomJoined', 'roomEdited'); version skew where a caller emits an event the handler version does not know; plugins introducing events without extending this switch.

Common situations: Fork/custom deployments emitting bespoke events; partial upgrades leaving emit sites and the handler out of sync; copy-paste typos in event names.

Related errors


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