{"record":{"id":"5ca93d50f504d3d2","repo":"RocketChat/Rocket.Chat","slug":"the-property-end-query-parameter-must-be-a-va","errorCode":null,"errorMessage":"The \"${property}.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/server/api/v1/omnichannel/rooms.ts","lineNumber":19,"sourceCode":"import { LivechatRooms } from '@rocket.chat/models';\nimport { isGETLivechatRoomsParams } from '@rocket.chat/rest-typings';\n\nimport { API } from '../..';\nimport { findRooms } from './lib/rooms';\nimport { hasPermissionAsync } from '../../../lib/authorization/hasPermission';\nimport { getPaginationItems } from '../../lib/getPaginationItems';\n\nconst validateDateParams = (property: string, date?: string) => {\n\tlet parsedDate: { start?: string; end?: string } | undefined = undefined;\n\tif (date) {\n\t\tparsedDate = JSON.parse(date) as { start?: string; end?: string };\n\t}\n\n\tif (parsedDate?.start && isNaN(Date.parse(parsedDate.start))) {\n\t\tthrow new Error(`The \"${property}.start\" query parameter must be a valid date.`);\n\t}\n\tif (parsedDate?.end && isNaN(Date.parse(parsedDate.end))) {\n\t\tthrow new Error(`The \"${property}.end\" query parameter must be a valid date.`);\n\t}\n\treturn parsedDate;\n};\n\nconst isBoolean = (value?: string | boolean): boolean => value === 'true' || value === 'false' || typeof value === 'boolean';\n\nAPI.v1.addRoute(\n\t'livechat/rooms',\n\t{ authRequired: true, validateParams: isGETLivechatRoomsParams },\n\t{\n\t\tasync get() {\n\t\t\tconst { offset, count } = await getPaginationItems(this.queryParams);\n\t\t\tconst { sort, fields, query } = await this.parseJsonQuery();\n\t\t\tconst { agents, departmentId, open, tags, roomName, onhold, queued, units } = this.queryParams;\n\t\t\tconst { createdAt, customFields, closedAt } = this.queryParams;\n\n\t\t\tconst createdAtParam = validateDateParams('createdAt', createdAt);\n\t\t\tconst closedAtParam = validateDateParams('closedAt', closedAt);","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/omnichannel/rooms.ts#L1-L37","documentation":"Thrown by GET /api/v1/livechat/rooms when the JSON-encoded date-range query parameter's end value fails Date.parse (NaN). Same mechanism as the .start variant, but for the upper bound of the created/closed range; the message names the failing property so .end failures are distinguishable from .start failures.","triggerScenarios":"created/closed object where end is an unparseable string ('2024-02-31', 'tomorrow', '2024-13-01T00:00:00Z'), end computed from an invalid client-side Date, or range JSON mangled by missing URL-encoding so the end value arrives truncated.","commonSituations":"Open-ended pickers defaulting end to '' or null that then gets stringified; timezone suffix typos; date pickers emitting locale order (mm/dd vs dd/mm confusion silently shifts or invalidates dates).","solutions":["Compute end via toISOString() from a validated Date; omit end entirely for open-ended ranges instead of sending a sentinel","Client-side guard: only include start/end keys whose Date.parse is finite","URL-encode the whole JSON payload with encodeURIComponent"],"exampleFix":"// before\nconst range = { start: '2024-12-01', end: endDate ?? '' }; // '' → sent → NaN\nconst q = `closed=${JSON.stringify(range)}`;\n\n// after\nconst range = { start: '2024-12-01' };\nif (endDate instanceof Date && !Number.isNaN(endDate.getTime())) range.end = endDate.toISOString();\nconst q = `closed=${encodeURIComponent(JSON.stringify(range))}`;","handlingStrategy":"validation","validationCode":"const range = { start: startISO };\nif (endDate instanceof Date && !Number.isNaN(endDate.getTime())) {\n  range.end = endDate.toISOString(); // omit entirely when unavailable\n}\nconst q = `closed=${encodeURIComponent(JSON.stringify(range))}`;","typeGuard":"function isValidRangeValue(v) {\n  return typeof v === 'string' && v.length > 0 && !Number.isNaN(Date.parse(v));\n}","tryCatchPattern":null,"preventionTips":["Omit end rather than sending '' or null for open-ended ranges","Validate both bounds with Date.parse before building the query","Beware date-picker locale ordering (dd/mm vs mm/dd)"],"tags":["omnichannel","livechat","query-params","date-validation","rest-api"],"backgroundTag":"query-parameter-validation-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}