{"record":{"id":"cf25a338ed8d9737","repo":"RocketChat/Rocket.Chat","slug":"the-end-query-parameter-must-be-a-valid-date","errorCode":null,"errorMessage":"The \"end\" query parameter must be a valid date.","messagePattern":"The \"end\" query parameter must be a valid date\\.","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/ee/server/api/v1/omnichannel/reports.ts","lineNumber":20,"sourceCode":"import type { Moment } from 'moment';\nimport moment from 'moment';\n\nimport {\n\tfindAllConversationsBySourceCached,\n\tfindAllConversationsByStatusCached,\n\tfindAllConversationsByDepartmentCached,\n\tfindAllConversationsByTagsCached,\n\tfindAllConversationsByAgentsCached,\n} from './lib/dashboards';\nimport { API } from '../../../../../server/api';\nimport { restrictQuery } from '../../../lib/omnichannel/restrictQuery';\n\nconst checkDates = (start: Moment, end: Moment) => {\n\tif (!start.isValid()) {\n\t\tthrow new Error('The \"start\" query parameter must be a valid date.');\n\t}\n\tif (!end.isValid()) {\n\t\tthrow new Error('The \"end\" query parameter must be a valid date.');\n\t}\n\t// Check dates are no more than 1 year apart using moment\n\t// 1.01 === \"we allow to pass year by some hours/days\"\n\tif (moment(end).startOf('day').diff(moment(start).startOf('day'), 'year', true) > 1.01) {\n\t\tthrow new Error('The \"start\" and \"end\" query parameters must be less than 1 year apart.');\n\t}\n\n\tif (start.isAfter(end)) {\n\t\tthrow new Error('The \"start\" query parameter must be before the \"end\" query parameter.');\n\t}\n};\n\nAPI.v1.addRoute(\n\t'livechat/analytics/dashboards/conversations-by-source',\n\t{\n\t\tauthRequired: true,\n\t\tpermissionsRequired: ['view-livechat-reports'],\n\t\tvalidateParams: isGETDashboardConversationsByType,","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/api/v1/omnichannel/reports.ts#L2-L38","documentation":"checkDates validates the moment-parsed end query parameter on every livechat/analytics/dashboards/* route; if end is missing, empty, or unparseable, this error is thrown before the report runs. start is checked first, so a bad start masks a bad end.","triggerScenarios":"GET /api/v1/livechat/analytics/dashboards/conversations-by-status?start=2024-01-01&end= (or end omitted, or end=whenever), leaving moment(end).isValid() false.","commonSituations":"Date-range pickers that submit an empty 'to' field; URL builders that drop falsy params; end computed from an undefined variable serialized as the string 'undefined'.","solutions":["Send end as ISO 8601, e.g. 2024-12-31T23:59:59.999Z.","Make end required in your client validation and never let it serialize as undefined/empty.","If the intent is 'up to now', explicitly set end to the current time in ISO format."],"exampleFix":"// before\napi.get(url, { params: { start: '2024-01-01', end: undefined } });\n\n// after\napi.get(url, { params: { start: '2024-01-01', end: new Date().toISOString() } });","handlingStrategy":"validation","validationCode":"const isIsoDate = (v: string | undefined): v is string => !!v && !Number.isNaN(Date.parse(v));\nif (!isIsoDate(end)) end = new Date().toISOString(); // default 'up to now'\nif (!isIsoDate(start)) throw new Error('start must be a valid ISO 8601 date');\nawait api.get(url, { params: { start, end } });","typeGuard":null,"tryCatchPattern":"try {\n  await api.get(url, { params: { start, end } });\n} catch (e) {\n  if (e?.response?.data?.error === 'The \"end\" query parameter must be a valid date.') {\n    // fill/normalize end (e.g. now) and retry once\n  } else throw e;\n}","preventionTips":["Never let end serialize as undefined or empty string.","Default end to 'now' explicitly in report clients.","Check start first — a bad start masks a bad end."],"tags":["omnichannel","analytics","date-validation","rest-api","momentjs"],"backgroundTag":"invalid-date-format","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}