{"record":{"id":"24d6f76a37fb9287","repo":"RocketChat/Rocket.Chat","slug":"error-roomid-param-invalid-24d6f7","errorCode":"error-roomId-param-invalid","errorMessage":"The \"updatedSince\" query parameter must be a valid date.","messagePattern":"The \"updatedSince\" query parameter must be a valid date\\.","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/api/v1/permissions.ts","lineNumber":125,"sourceCode":"\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\tenum: [true],\n\t\t\t\t\t\t\tdescription: 'Indicates if the request was successful.',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\trequired: ['update', 'remove', '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\tlet updatedSinceDate: Date | undefined;\n\t\t\tif (updatedSince) {\n\t\t\t\tif (isNaN(Date.parse(updatedSince))) {\n\t\t\t\t\tthrow new Meteor.Error('error-roomId-param-invalid', 'The \"updatedSince\" query parameter must be a valid date.');\n\t\t\t\t}\n\t\t\t\tupdatedSinceDate = new Date(updatedSince);\n\t\t\t}\n\n\t\t\tconst result = (await permissionsGetMethod(updatedSinceDate)) as {\n\t\t\t\tupdate: IPermission[];\n\t\t\t\tremove: IPermission[];\n\t\t\t};\n\n\t\t\tif (Array.isArray(result)) {\n\t\t\t\treturn API.v1.success({\n\t\t\t\t\tupdate: result,\n\t\t\t\t\tremove: [],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn API.v1.success(result);\n\t\t},","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/permissions.ts#L107-L143","documentation":"Thrown as Meteor.Error('error-roomId-param-invalid', 'The \"updatedSince\" query parameter must be a valid date.') on GET /api/v1/permissions when updatedSince is supplied but Date.parse(updatedSince) is NaN. Note the error code is misleadingly named 'roomId-param-invalid' but the message correctly describes the updatedSince problem - the code is a reused generic param-invalid code, not a permissions-specific one.","triggerScenarios":"GET /api/v1/v1/permissions?updatedSince=foo or ?updatedSince=2024-13-45 - any string that is not parseable by Date.parse. ISO-8601 like '2024-01-01T00:00:00.000Z' is the expected format.","commonSituations":"Client formatting dates with locale strings that Date.parse rejects; passing a Unix epoch number as a string without conversion; trailing timezone garbage.","solutions":["Send updatedSince as an ISO-8601 timestamp (e.g., new Date().toISOString()).","Validate with !isNaN(Date.parse(value)) client-side before the request.","Omit updatedSince entirely to get the full permission list rather than a delta."],"exampleFix":"// before\nfetch(`/api/v1/permissions?updatedSince=${localDateString}`);\n\n// after\nconst iso = new Date(localDateString).toISOString(); // 'YYYY-MM-DDTHH:mm:ss.sssZ'\nfetch(`/api/v1/permissions?updatedSince=${encodeURIComponent(iso)}`);","handlingStrategy":"validation","validationCode":"let qs = '';\nif (updatedSince) {\n  const ms = Date.parse(updatedSince);\n  if (Number.isNaN(ms)) throw new Error('updatedSince must be ISO-8601');\n  qs = '?updatedSince=' + encodeURIComponent(new Date(ms).toISOString());\n}\nawait fetch('/api/v1/v1/permissions' + qs);","typeGuard":"function isIsoDate(s: unknown): s is string {\n  return typeof s === 'string' && !Number.isNaN(Date.parse(s));\n}","tryCatchPattern":"null","preventionTips":["Always send updatedSince as new Date(...).toISOString().","Omit updatedSince to get the full permission list.","Note the misleading 'error-roomId-param-invalid' code; key off the message or status."],"tags":["permissions","validation","date","query-param"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}