RocketChat/Rocket.Chat · error · Meteor.Error

The required "_id" query param is missing.

Error message

The required "_id" query param is missing.

What it means

Thrown by POST emoji-custom.update when the multipart form field '_id' is missing/falsy. DEFECT: it is built as new Meteor.Error('The required "_id" query param is missing.') — the human message occupies the error-CODE slot, so there is no structured code and clients cannot match on a stable key. Also note it says 'query param' but _id is actually a form field.

Source

Thrown at apps/meteor/server/api/v1/emoji-custom.ts:247

					required: ['success'],
					additionalProperties: false,
				}),
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
			},
		},
		async function action() {
			const emoji = await getUploadFormData(
				{
					request: this.request,
				},
				{ field: 'emoji', sizeLimit: settings.get('FileUpload_MaxFileSize'), fileOptional: true },
			);

			const { fields, fileBuffer, mimetype } = emoji;

			if (!fields._id) {
				throw new Meteor.Error('The required "_id" query param is missing.');
			}

			const emojiToUpdate = await EmojiCustom.findOneById<Pick<IEmojiCustom, 'name' | 'extension'>>(fields._id, {
				projection: { name: 1, extension: 1 },
			});
			if (!emojiToUpdate) {
				throw new Meteor.Error('Emoji not found.');
			}

			const emojiData: EmojiData = {
				previousName: emojiToUpdate.name,
				previousExtension: emojiToUpdate.extension,
				aliases: fields.aliases || '',
				name: fields.name,
				extension: fields.extension,
				_id: fields._id,
				newFile: false,
			};

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Always include the existing emoji's _id in the emoji form data when updating.
  2. Client-side assert _id is present before opening the upload.
  3. When matching errors, key on the message substring rather than expecting a normal code.

Example fix

// before
const fd = new FormData(); fd.append('name', newName); // forgot _id
// after
if (!emojiId) throw new Error('no emoji selected to update');
const fd = new FormData(); fd.append('_id', emojiId); fd.append('name', newName);
Defensive patterns

Strategy: validation

Validate before calling

if (!emojiId) throw new Error('select an emoji to update');
const fd = new FormData(); fd.append('_id', emojiId);

Type guard

function hasId(fields): fields is { _id: string } { return typeof fields?._id === 'string' && fields._id.length > 0; }

Try / catch

try { await updateEmojiCustom(fd); }
catch (e) {
  // note: the message IS the code here (no structured code)
  if (/"_id" query param is missing/i.test(e?.error || '')) { /* add _id field */) }
  else throw e;
}

Prevention

When it happens

Trigger: Update call without the _id field in the multipart body; field name typo (e.g. 'id' instead of '_id'); form serialization drops falsy ids.

Common situations: Client form omits the selected emoji's id; refactor changed the field name; building FormData from an object without _id.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/1e96f4d6277b2ec6. Report an issue: GitHub.