{"record":{"id":"93f39eb6561771ab","repo":"RocketChat/Rocket.Chat","slug":"error-emoji-param-not-provided","errorCode":"error-emoji-param-not-provided","errorMessage":"The required \"emoji\" param is missing.","messagePattern":"The required \"emoji\" param is missing\\.","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/chat.ts","lineNumber":557,"sourceCode":"\t\t\t\t\t},\n\t\t\t\t\trequired: ['success'],\n\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t}),\n\t\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t},\n\t\t},\n\t\tasync function action() {\n\t\t\tconst msg = await Messages.findOneById(this.bodyParams.messageId);\n\n\t\t\tif (!msg) {\n\t\t\t\tthrow new Meteor.Error('error-message-not-found', 'The provided \"messageId\" does not match any existing message.');\n\t\t\t}\n\n\t\t\tconst emoji = 'emoji' in this.bodyParams ? this.bodyParams.emoji : (this.bodyParams as { reaction: string }).reaction;\n\n\t\t\tif (!emoji) {\n\t\t\t\tthrow new Meteor.Error('error-emoji-param-not-provided', 'The required \"emoji\" param is missing.');\n\t\t\t}\n\n\t\t\tawait executeSetReaction(this.userId, emoji, msg, this.bodyParams.shouldReact);\n\n\t\t\treturn API.v1.success();\n\t\t},\n\t)\n\t.post(\n\t\t'chat.reportMessage',\n\t\t{\n\t\t\tauthRequired: true,\n\t\t\tbody: isChatReportMessageProps,\n\t\t\tresponse: {\n\t\t\t\t200: ajv.compile<void>({\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tsuccess: {\n\t\t\t\t\t\t\ttype: 'boolean',","sourceCodeStart":539,"sourceCodeEnd":575,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/e4b8178b205510181a96ceefee043d0abcd13e5a/apps/meteor/server/api/v1/chat.ts#L539-L575","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send a non-empty emoji name: { \"messageId\": \"...\", \"emoji\": \"+1\" } - use the new `emoji` key, not `reaction`.","Disable the submit path in your UI until an emoji is actually chosen.","Log the outgoing body when this error appears - it almost always means the emoji field serialized to an empty string.","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')."],"exampleFix":"// before\nawait rc.post('/api/v1/chat.react', { messageId, emoji: selected ?? '' }); // '' passes schema, fails handler\n\n// after\nif (!selected) throw new Error('pick an emoji first');\nawait rc.post('/api/v1/chat.react', { messageId, emoji: selected });","handlingStrategy":"validation","validationCode":"const isReactPayload = (\n  p: { emoji?: unknown; reaction?: unknown },\n): p is { emoji: string } =>\n  (typeof p.emoji === 'string' && p.emoji.length > 0) ||\n  (typeof p.reaction === 'string' && p.reaction.length > 0);\nif (!isReactPayload(payload)) throw new Error('emoji required');\nawait rc.post('/api/v1/chat.react', { messageId, ...payload });","typeGuard":"const isReactPayload = (p: { emoji?: unknown; reaction?: unknown }): p is { emoji: string } =>\n  (typeof p.emoji === 'string' && p.emoji.length > 0) ||\n  (typeof p.reaction === 'string' && p.reaction.length > 0);","tryCatchPattern":"try {\n  await rc.post('/api/v1/chat.react', { messageId, emoji });\n} catch (e) {\n  if (e?.errorType === 'error-emoji-param-not-provided') promptEmojiSelection();\n  else throw e;\n}","preventionTips":["Remember empty-string emoji passes schema (no minLength) - only your client check catches it.","Use the `emoji` key (not legacy `reaction`) and send Rocket.Chat emoji names like '+1' or 'tada'."],"tags":["rocket-chat","rest-api","reactions","missing-parameter","emoji","chat-react"],"backgroundTag":"missing-required-argument","analyzedSha":"e4b8178b205510181a96ceefee043d0abcd13e5a","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}