RocketChat/Rocket.Chat · error · Meteor.Error
error-updatedSince-param-invalid
error-updatedSince-param-invalid
Error message
The "updatedSince" query parameter must be a valid date.
What it means
Thrown by GET /api/v1/rooms.get when the updatedSince query parameter is present but Date.parse(updatedSince) returns NaN, i.e. the string is not a parseable date. The endpoint expects an ISO 8601 timestamp and uses it to return only rooms updated after that instant (plus removed rooms). Any locale-specific or non-standard format risks rejection.
Solutions
- Always send ISO 8601 UTC: new Date().toISOString() (e.g. 2026-08-18T12:00:00.000Z)
- Convert epoch values before sending: new Date(epochMs).toISOString()
- Validate client-side with Number.isNaN(Date.parse(value)) and fix before the request
- Omit updatedSince entirely when you want the full room list snapshot
Example fix
// before
await sdk.get('rooms.get', { updatedSince: String(Date.now()) }); // epoch millis -> NaN parse
// after
await sdk.get('rooms.get', { updatedSince: new Date().toISOString() }); // 2026-08-18T12:00:00.000Z Defensive patterns
Strategy: validation
Validate before calling
if (updatedSince && Number.isNaN(Date.parse(updatedSince))) {
updatedSince = new Date(updatedSinceEpochMs).toISOString();
} Try / catch
try {
await sdk.get('rooms.get', { updatedSince });
} catch (e: any) {
if (e?.response?.data?.errorType === 'error-updatedSince-param-invalid') {
return sdk.get('rooms.get', { updatedSince: new Date().toISOString() }); // one-shot fallback
}
throw e;
} Prevention
- Centralize date serialization: every outbound timestamp goes through toISOString()
- Never pass Date.now() output directly as updatedSince
- Add a lint/test assertion on the query builder for ISO format
When it happens
Trigger: GET rooms.get?updatedSince=1650000000000 (epoch milliseconds as a string, not parseable); updatedSince=18/08/2026 (locale format); a truncated timestamp like 2026-08-18T12:60:00Z; sending a timezone name like UTC.
Common situations: Passing Date.now() output directly instead of new Date().toISOString(); client libraries formatting dates per user locale; database timestamps copied as epoch numbers; timezone-less local formats like 2026-08-18 14:30 (parseable in most engines but non-portable).
Related errors
- error-roomid-param-not-provided
- error-action-not-allowed
- error-cannot-delete-team-channel
- error-invalid-param
- error-invalid-params-custom
AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-08-18).
Data as JSON: /api/errors/ebe277bb25e9b027.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/api/v1/rooms.ts:248
properties: {
update: { type: 'array', items: { type: 'object' } }, // relaxed: IRoom composed with lastMessage
remove: { type: 'array', items: { type: 'object' } }, // relaxed: IRoom composed with lastMessage
success: { type: 'boolean', enum: [true] },
},
required: ['update', 'remove', 'success'],
additionalProperties: false,
}),
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
},
},
async function action() {
const { updatedSince } = this.queryParams;
let updatedSinceDate;
if (updatedSince) {
if (isNaN(Date.parse(updatedSince))) {
throw new Meteor.Error('error-updatedSince-param-invalid', 'The "updatedSince" query parameter must be a valid date.');
} else {
updatedSinceDate = new Date(updatedSince);
}
}
let result = await roomsGetMethod(this.userId, updatedSinceDate);
if (Array.isArray(result)) {
result = {
update: result,
remove: [],
};
}
return API.v1.success({
update: await Promise.all(result.update.map((room) => composeRoomWithLastMessage(room, this.userId))),
remove: await Promise.all(result.remove.map((room) => composeRoomWithLastMessage(room, this.userId))),
});View on GitHub (pinned to e4b8178b20)