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
- Send lastUpdate as strict ISO 8601 UTC: new Date().toISOString() → '2024-05-01T12:34:56.789Z'.
- If you hold a epoch number, convert first: new Date(epochMs).toISOString().
- URL-encode the param (encodeURIComponent) so timezone offsets and colons survive transport.
- 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
- Always serialize dates with toISOString(); never send epoch numbers or locale formats.
- Encode query params (encodeURIComponent) so '+' in timezone offsets does not degrade to a space.
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
- error-param-required
- Cannot send system messages using 'chat.sendMessage'
- error-emoji-param-not-provided
- error-invalid-message
- error-invalid-role
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)