RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-param

error-invalid-param

Error message

updatedSince must be a valid date string

What it means

Thrown by GET roles.sync when updatedSince is present in the query but Date.parse(updatedSince) returns NaN. The query schema only requires updatedSince be a string; semantic date validity is enforced here in the action. Returns a structured Meteor.Error('error-invalid-param', ...).

Source

Thrown at apps/meteor/server/api/v1/roles.ts:103

								update: { type: 'array', items: { $ref: '#/components/schemas/IRole' } },
								remove: { type: 'array', items: { $ref: '#/components/schemas/IRole' } },
							},
							required: ['update', 'remove'],
						},
						success: { type: 'boolean', enum: [true] },
					},
					required: ['roles', 'success'],
					additionalProperties: false,
				}),
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
			},
		},
		async function action() {
			const { updatedSince } = this.queryParams;

			if (updatedSince && Number.isNaN(Date.parse(updatedSince))) {
				throw new Meteor.Error('error-invalid-param', 'updatedSince must be a valid date string');
			}

			return API.v1.success({
				roles: {
					update: await Roles.findByUpdatedDate(new Date(updatedSince || 0)).toArray(),
					remove: await Roles.trashFindDeletedAfter(new Date(updatedSince || 0)).toArray(),
				},
			});
		},
	)
	.post(
		'roles.addUserToRole',
		{
			authRequired: true,
			body: isRoleAddUserToRoleProps,
			response: {
				200: ajv.compile<{ role: IRole }>({
					type: 'object',

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Send updatedSince as an ISO 8601 string (new Date().toISOString()), which Date.parse always accepts.
  2. Omit updatedSince entirely to sync all roles rather than since a date.
  3. Validate the string client-side with !Number.isNaN(Date.parse(value)) before sending.

Example fix

// before
const since = new Date().toLocaleString(); // not reliably parseable
fetch(`/api/v1/roles.sync?updatedSince=${encodeURIComponent(since)}`);

// after
const since = new Date().toISOString(); // ISO 8601, always parseable
fetch(`/api/v1/roles.sync?updatedSince=${encodeURIComponent(since)}`);
Defensive patterns

Strategy: validation

Validate before calling

// Validate updatedSince is parseable before sending
function toValidSince(date?: Date): string | undefined {
  if (!date) return undefined;
  const iso = date.toISOString();
  if (Number.isNaN(Date.parse(iso))) throw new Error('invalid date');
  return iso;
}
const since = toValidSince(lastSync);
fetch(`/api/v1/roles.sync${since ? `?updatedSince=${encodeURIComponent(since)}` : ''}`);

Type guard

function isParseableDate(value: string): boolean {
  return typeof value === 'string' && !Number.isNaN(Date.parse(value));
}

Try / catch

try {
  await fetch(`/api/v1/roles.sync?updatedSince=${encodeURIComponent(since)}`).then(r => r.json());
} catch (e) {
  if (e.error === 'error-invalid-param') { /* reformat date as ISO 8601 and retry once */ }
}

Prevention

When it happens

Trigger: GET /api/v1/roles.sync?updatedSince=<not-a-date> e.g. 'yesterday', '2024-13-99', a bare number, or a locale-specific string Date.parse cannot handle.

Common situations: Client formats dates with toLocaleString instead of toISOString; passing a unix epoch number as a string without conversion; timezone/offset tokens the parser rejects.

Related errors


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