RocketChat/Rocket.Chat · error · Meteor.Error

error-emoji-param-not-provided

error-emoji-param-not-provided

Error message

The required "emoji" param is missing.

What it means

Thrown by POST chat.react (apps/meteor/server/api/v1/chat.ts:553) when neither emoji nor the legacy reaction body param yields a value. The schema (ChatReactSchema oneOf) requires emoji or reaction, but neither branch sets minLength - so emoji: "" (or reaction: "") passes validation and only fails this runtime truthiness check with error-emoji-param-not-provided. `reaction` is the deprecated alias; `emoji` is the current name.

Solutions

  1. Send a non-empty emoji name: { "messageId": "...", "emoji": "+1" } - use the new `emoji` key, not `reaction`.
  2. Disable the submit path in your UI until an emoji is actually chosen.
  3. Log the outgoing body when this error appears - it almost always means the emoji field serialized to an empty string.
  4. Ensure emoji values are Rocket.Chat emoji names (e.g. 'tada', '+1'), not unicode chars or URLs (those fail later inside setReaction with 'Invalid emoji provided').

Example fix

// before
await rc.post('/api/v1/chat.react', { messageId, emoji: selected ?? '' }); // '' passes schema, fails handler

// after
if (!selected) throw new Error('pick an emoji first');
await rc.post('/api/v1/chat.react', { messageId, emoji: selected });
Defensive patterns

Strategy: validation

Validate before calling

const isReactPayload = (
  p: { emoji?: unknown; reaction?: unknown },
): p is { emoji: string } =>
  (typeof p.emoji === 'string' && p.emoji.length > 0) ||
  (typeof p.reaction === 'string' && p.reaction.length > 0);
if (!isReactPayload(payload)) throw new Error('emoji required');
await rc.post('/api/v1/chat.react', { messageId, ...payload });

Type guard

const isReactPayload = (p: { emoji?: unknown; reaction?: unknown }): p is { emoji: string } =>
  (typeof p.emoji === 'string' && p.emoji.length > 0) ||
  (typeof p.reaction === 'string' && p.reaction.length > 0);

Try / catch

try {
  await rc.post('/api/v1/chat.react', { messageId, emoji });
} catch (e) {
  if (e?.errorType === 'error-emoji-param-not-provided') promptEmojiSelection();
  else throw e;
}

Prevention

When it happens

Trigger: POST /api/v1/chat.react with messageId of a real message plus emoji: "" or reaction: ""; or a payload where the client's emoji variable is undefined/empty after being serialized. Also seen when clients send both keys but both are empty strings.

Common situations: UI reaction pickers that submit before an emoji is selected; templated payloads like { messageId, emoji: `${name}` } where name is empty; integrations migrating from the old `reaction` param that send reaction: "" while adding emoji; emoji values stripped by sanitization.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/api/v1/chat.ts:557

					},
					required: ['success'],
					additionalProperties: false,
				}),
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
			},
		},
		async function action() {
			const msg = await Messages.findOneById(this.bodyParams.messageId);

			if (!msg) {
				throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.');
			}

			const emoji = 'emoji' in this.bodyParams ? this.bodyParams.emoji : (this.bodyParams as { reaction: string }).reaction;

			if (!emoji) {
				throw new Meteor.Error('error-emoji-param-not-provided', 'The required "emoji" param is missing.');
			}

			await executeSetReaction(this.userId, emoji, msg, this.bodyParams.shouldReact);

			return API.v1.success();
		},
	)
	.post(
		'chat.reportMessage',
		{
			authRequired: true,
			body: isChatReportMessageProps,
			response: {
				200: ajv.compile<void>({
					type: 'object',
					properties: {
						success: {
							type: 'boolean',

View on GitHub (pinned to e4b8178b20)