{"record":{"id":"86ef867de50e5839","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-param-86ef86","errorCode":"error-invalid-param","errorMessage":"updatedSince must be a valid date string","messagePattern":"updatedSince must be a valid date string","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/roles.ts","lineNumber":103,"sourceCode":"\t\t\t\t\t\t\t\tupdate: { type: 'array', items: { $ref: '#/components/schemas/IRole' } },\n\t\t\t\t\t\t\t\tremove: { type: 'array', items: { $ref: '#/components/schemas/IRole' } },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\trequired: ['update', 'remove'],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess: { type: 'boolean', enum: [true] },\n\t\t\t\t\t},\n\t\t\t\t\trequired: ['roles', 'success'],\n\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t}),\n\t\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t\t},\n\t\t},\n\t\tasync function action() {\n\t\t\tconst { updatedSince } = this.queryParams;\n\n\t\t\tif (updatedSince && Number.isNaN(Date.parse(updatedSince))) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-param', 'updatedSince must be a valid date string');\n\t\t\t}\n\n\t\t\treturn API.v1.success({\n\t\t\t\troles: {\n\t\t\t\t\tupdate: await Roles.findByUpdatedDate(new Date(updatedSince || 0)).toArray(),\n\t\t\t\t\tremove: await Roles.trashFindDeletedAfter(new Date(updatedSince || 0)).toArray(),\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t)\n\t.post(\n\t\t'roles.addUserToRole',\n\t\t{\n\t\t\tauthRequired: true,\n\t\t\tbody: isRoleAddUserToRoleProps,\n\t\t\tresponse: {\n\t\t\t\t200: ajv.compile<{ role: IRole }>({\n\t\t\t\t\ttype: 'object',","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/roles.ts#L85-L121","documentation":"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', ...).","triggerScenarios":"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.","commonSituations":"Client formats dates with toLocaleString instead of toISOString; passing a unix epoch number as a string without conversion; timezone/offset tokens the parser rejects.","solutions":["Send updatedSince as an ISO 8601 string (new Date().toISOString()), which Date.parse always accepts.","Omit updatedSince entirely to sync all roles rather than since a date.","Validate the string client-side with !Number.isNaN(Date.parse(value)) before sending."],"exampleFix":"// before\nconst since = new Date().toLocaleString(); // not reliably parseable\nfetch(`/api/v1/roles.sync?updatedSince=${encodeURIComponent(since)}`);\n\n// after\nconst since = new Date().toISOString(); // ISO 8601, always parseable\nfetch(`/api/v1/roles.sync?updatedSince=${encodeURIComponent(since)}`);","handlingStrategy":"validation","validationCode":"// Validate updatedSince is parseable before sending\nfunction toValidSince(date?: Date): string | undefined {\n  if (!date) return undefined;\n  const iso = date.toISOString();\n  if (Number.isNaN(Date.parse(iso))) throw new Error('invalid date');\n  return iso;\n}\nconst since = toValidSince(lastSync);\nfetch(`/api/v1/roles.sync${since ? `?updatedSince=${encodeURIComponent(since)}` : ''}`);","typeGuard":"function isParseableDate(value: string): boolean {\n  return typeof value === 'string' && !Number.isNaN(Date.parse(value));\n}","tryCatchPattern":"try {\n  await fetch(`/api/v1/roles.sync?updatedSince=${encodeURIComponent(since)}`).then(r => r.json());\n} catch (e) {\n  if (e.error === 'error-invalid-param') { /* reformat date as ISO 8601 and retry once */ }\n}","preventionTips":["Always serialize dates with toISOString().","Omit updatedSince to sync everything instead of guessing a date format."],"tags":["roles","rest-api","validation","date","query-params"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}