RocketChat/Rocket.Chat · error · Meteor.Error

error-lastUpdate-param-invalid

error-lastUpdate-param-invalid

Error message

The "lastUpdate" query parameter must be a valid date

What it means

Thrown by GET chat.syncMessages (apps/meteor/server/api/v1/chat.ts:723) when lastUpdate is provided but Date.parse(lastUpdate) is NaN, with error-lastUpdate-param-invalid. The handler will construct new Date(lastUpdate) for the Mongo query, so an unparseable timestamp is rejected up front. The query schema types lastUpdate as a plain string, so format errors are caught here, not by schema.

Solutions

  1. Send lastUpdate as strict ISO 8601 UTC: new Date().toISOString() → '2024-05-01T12:34:56.789Z'.
  2. If you hold a epoch number, convert first: new Date(epochMs).toISOString().
  3. URL-encode the param (encodeURIComponent) so timezone offsets and colons survive transport.
  4. Avoid date-fns/moment default formats that emit slashes or ambiguous orders; test with Date.parse() client-side before sending.

Example fix

// before
rc.get('/api/v1/chat.syncMessages', { params: { roomId, lastUpdate: String(Date.now()) } }); // epoch string -> NaN parse

// after
rc.get('/api/v1/chat.syncMessages', { params: { roomId, lastUpdate: new Date().toISOString() } });
Defensive patterns

Strategy: validation

Validate before calling

const isValidRocketDate = (s: string) => !Number.isNaN(Date.parse(s));
const lastUpdate = new Date(sinceMs).toISOString();
if (!isValidRocketDate(lastUpdate)) throw new Error('lastUpdate must be ISO 8601');
await rc.get('/api/v1/chat.syncMessages', { params: { roomId, lastUpdate } });

Type guard

const isIsoDateString = (s: unknown): s is string =>
  typeof s === 'string' && !Number.isNaN(Date.parse(s));

Try / catch

try {
  await rc.get('/api/v1/chat.syncMessages', { params: { roomId, lastUpdate } });
} catch (e) {
  if (e?.errorType === 'error-lastUpdate-param-invalid') {
    await retryWithIso(); // re-send lastUpdate = new Date().toISOString()
  } else throw e;
}

Prevention

When it happens

Trigger: GET /api/v1/chat.syncMessages?roomId=...&lastUpdate=<bad> where <bad> is a non-ISO string: '2024/05/01' (slashes), '01-05-2024', a Unix epoch number passed as string ('1714521600'), 'now', or a locale-formatted date. Only ISO 8601 ('2024-05-01T00:00:00Z' or '2024-05-01') parses reliably.

Common situations: Passing seconds/milliseconds since epoch instead of a date string; using the local Date.toString() output (locale-dependent); URL-encoding bugs that mangle the '+' timezone offset into a space (e.g. 2024-05-01T00:00:00+00:00 sent unencoded); dates built with custom formatters.

Related errors


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

Appendix: source

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

					additionalProperties: false,
				}),
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
			},
		},
		async function action() {
			const { roomId, lastUpdate, fromTs, count, next, previous, type } = this.queryParams;

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

			if (!lastUpdate && !type) {
				throw new Meteor.Error('error-param-required', 'The "type" or "lastUpdate" parameters must be provided');
			}

			if (lastUpdate && isNaN(Date.parse(lastUpdate))) {
				throw new Meteor.Error('error-lastUpdate-param-invalid', 'The "lastUpdate" query parameter must be a valid date');
			}

			const getMessagesQuery = {
				...(lastUpdate && { lastUpdate: new Date(lastUpdate) }),
				...(fromTs && { fromTs: new Date(fromTs) }),
				...(next && { next }),
				...(previous && { previous }),
				...(count && { count }),
				...(type && { type }),
			};

			const result = await getMessageHistory(roomId, this.userId, getMessagesQuery);

			if (!result) {
				return API.v1.failure();
			}

			return API.v1.success({

View on GitHub (pinned to e4b8178b20)