RocketChat/Rocket.Chat · error · Meteor.Error

error-roomId-param-invalid

error-roomId-param-invalid

Error message

The "${paramName}" query parameter must be a valid date.

What it means

Thrown by the validateDateParam helper (used by emoji-custom list/sync endpoints) when a provided date parameter cannot construct a valid Date. NOTABLE BUG: the error CODE is 'error-roomId-param-invalid' (copy-paste from elsewhere) while the MESSAGE correctly reports the date param is invalid. Clients branching on the code will be misled; match on HTTP 400 or the message text instead.

Source

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

});

const emojiCustomDeleteResponseSchema = ajv.compile<void>({
	type: 'object',
	properties: {
		success: { type: 'boolean', enum: [true] },
	},
	required: ['success'],
	additionalProperties: false,
});

function validateDateParam(paramName: string, paramValue: string | undefined): Date | undefined {
	if (!paramValue) {
		return undefined;
	}

	const date = new Date(paramValue);
	if (isNaN(date.getTime())) {
		throw new Meteor.Error('error-roomId-param-invalid', `The "${paramName}" query parameter must be a valid date.`);
	}

	return date;
}

const emojiCustomListResponseSchema = ajv.compile<{
	emojis: { update: IEmojiCustom[]; remove: WithId<RocketChatRecordDeleted<IEmojiCustom>>[] };
}>({
	type: 'object',
	properties: {
		emojis: {
			type: 'object',
			properties: {
				update: { type: 'array', items: { type: 'object' } },
				remove: { type: 'array', items: { type: 'object' } },
			},
			required: ['update', 'remove'],
		},

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Send an ISO-8601 UTC timestamp for any date param, or omit the param entirely when not needed.
  2. Do not branch on error code 'error-roomId-param-invalid' here — it is misnamed; match HTTP 400 or the message.
  3. Pre-validate with new Date(value); if isNaN, drop the param.

Example fix

// before
const url = `/api/v1/emoji-custom.list?since=${userInput}`; // userInput may be '12/04/24'
// after
const since = userInput ? new Date(userInput).toISOString() : undefined;
const qs = since ? `?since=${encodeURIComponent(since)}` : '';
const url = `/api/v1/emoji-custom.list${qs}`;
Defensive patterns

Strategy: validation

Validate before calling

function safeDateParam(value) {
  if (!value) return undefined;
  const d = new Date(value);
  if (isNaN(d.getTime())) throw new Error('invalid date param');
  return d.toISOString();
}
const since = safeDateParam(userInput); // append to query only if defined

Type guard

function isParsableDate(s): s is string { return typeof s === 'string' && !isNaN(new Date(s).getTime()); }

Try / catch

try { await listEmojiCustom({ since }); }
catch (e) {
  // NOTE: code is misnamed 'error-roomId-param-invalid'; match HTTP 400 or message
  if (e?.error === 'error-roomId-param-invalid' || /valid date/i.test(e.reason || '')) { /* drop date param, retry */) }
  else throw e;
}

Prevention

When it happens

Trigger: Passing ?since=foo, an empty string in a date field, a locale-formatted date, or a non-ISO value to an emoji-custom endpoint that calls validateDateParam.

Common situations: Client serializes a Date without toISOString; user-typed date in a regional format; empty string sent for an optional date param instead of omitting it.

Related errors


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