{"record":{"id":"8a7dcde249c63212","repo":"RocketChat/Rocket.Chat","slug":"error-roomid-param-invalid-8a7dcd","errorCode":"error-roomId-param-invalid","errorMessage":"The \"lastUpdate\" query parameter must be a valid date.","messagePattern":"The \"lastUpdate\" query parameter must be a valid date\\.","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/subscriptions.ts","lineNumber":60,"sourceCode":"});\n\nAPI.v1.get(\n\t'subscriptions.get',\n\t{\n\t\tauthRequired: true,\n\t\tquery: isSubscriptionsGetProps,\n\t\tresponse: {\n\t\t\t200: subscriptionsGetResponseSchema,\n\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t},\n\t},\n\tasync function action() {\n\t\tconst { updatedSince } = this.queryParams;\n\n\t\tlet updatedSinceDate: Date | undefined;\n\t\tif (updatedSince) {\n\t\t\tif (isNaN(Date.parse(updatedSince))) {\n\t\t\t\tthrow new Meteor.Error('error-roomId-param-invalid', 'The \"lastUpdate\" query parameter must be a valid date.');\n\t\t\t}\n\t\t\tupdatedSinceDate = new Date(updatedSince);\n\t\t}\n\n\t\tconst result = await getSubscriptions(this.userId, updatedSinceDate);\n\n\t\treturn API.v1.success(\n\t\t\tArray.isArray(result)\n\t\t\t\t? {\n\t\t\t\t\t\tupdate: result,\n\t\t\t\t\t\tremove: [],\n\t\t\t\t\t}\n\t\t\t\t: result,\n\t\t);\n\t},\n);\n\nconst subscriptionsGetOneResponseSchema = ajv.compile<{ subscription: ISubscription | null }>({","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/subscriptions.ts#L42-L78","documentation":"BUG-WARNING: the code and message disagree. The logic validates the 'updatedSince' (a.k.a. lastUpdate) DATE on GET subscriptions.get, but the thrown code is 'error-roomId-param-invalid' (about a room id) while the message talks about a date. Treat this as 'the updatedSince date could not be parsed'. A non-ISO/non-Date-parseable value triggers it.","triggerScenarios":"GET /api/v1/subscriptions.get?updatedSince=<unparseable> where Date.parse returns NaN. Despite the code name, no roomId is involved here.","commonSituations":"Passing a Unix epoch number; locale-formatted date string; URL encoding that mangles the timestamp; copying a value from a different API field format.","solutions":["Send updatedSince as ISO-8601 via new Date().toISOString() and URL-encode it.","Omit updatedSince to fetch all subscriptions.","Client-side: if isNaN(Date.parse(value)) is true, do not send the param.","File/track the code/message mismatch upstream — the code should be 'error-updatedSince-param-invalid'."],"exampleFix":"// before\nrest.get(`/api/v1/subscriptions.get?updatedSince=${Date.now()}`);\n\n// after\nconst since = new Date().toISOString();\nrest.get(`/api/v1/subscriptions.get?updatedSince=${encodeURIComponent(since)}`);","handlingStrategy":"validation","validationCode":"let url = '/api/v1/subscriptions.get';\nif (updatedSince) {\n  if (isNaN(Date.parse(updatedSince))) throw new Error('updatedSince must be a valid date');\n  url += `?updatedSince=${encodeURIComponent(updatedSince)}`;\n}","typeGuard":"function isValidIsoDate(s: unknown): s is string {\n  return typeof s === 'string' && !isNaN(Date.parse(s));\n}","tryCatchPattern":"try {\n  await rest.get(url);\n} catch (e) {\n  // NOTE: code is 'error-roomId-param-invalid' but the cause is a bad DATE\n  if (isMeteorError(e, 'error-roomId-param-invalid')) {\n    await rest.get('/api/v1/subscriptions.get'); // retry without cursor\n  } else throw e;\n}","preventionTips":["Source updatedSince from new Date().toISOString().","Omit the param for a full snapshot.","Remember the error code is misleading — it's a date problem."],"tags":["subscriptions","validation","date-format","rest-api","bug-mismatched-code"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}