{"record":{"id":"9c3b1fb2d5e85510","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-date","errorCode":"error-invalid-date","errorMessage":"Invalid expiresAt date string","messagePattern":"Invalid expiresAt date string","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/users.ts","lineNumber":2059,"sourceCode":"\t\t\t\t\treturn getUserFromParams(this.bodyParams);\n\t\t\t\t}\n\t\t\t})();\n\n\t\t\tif (!user) {\n\t\t\t\treturn API.v1.forbidden();\n\t\t\t}\n\n\t\t\tconst { status, message, expiresAt } = this.bodyParams;\n\n\t\t\tif (message && !settings.get('Accounts_AllowUserStatusMessageChange')) {\n\t\t\t\tthrow new Meteor.Error('error-not-allowed', 'Change status is not allowed', {\n\t\t\t\t\tmethod: 'users.setStatus',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst statusExpiresAt = expiresAt ? new Date(expiresAt) : undefined;\n\t\t\tif (statusExpiresAt && Number.isNaN(statusExpiresAt.getTime())) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-date', 'Invalid expiresAt date string', {\n\t\t\t\t\tmethod: 'users.setStatus',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (statusExpiresAt && statusExpiresAt.getTime() <= Date.now()) {\n\t\t\t\tthrow new Meteor.Error('error-invalid-date', 'expiresAt must be a future date', {\n\t\t\t\t\tmethod: 'users.setStatus',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// If status is missing (message-only update), keep the user's chosen status (statusDefault),\n\t\t\t// not the computed status — otherwise a transient auto-away/offline gets pinned as a manual claim.\n\t\t\tconst effectiveStatus = status || user.statusDefault || ('online' as UserStatus);\n\n\t\t\tif (effectiveStatus === 'offline' && !settings.get('Accounts_AllowInvisibleStatusOption')) {\n\t\t\t\tthrow new Meteor.Error('error-status-not-allowed', 'Invisible status is disabled', {\n\t\t\t\t\tmethod: 'users.setStatus',\n\t\t\t\t});","sourceCodeStart":2041,"sourceCodeEnd":2077,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/e4b8178b205510181a96ceefee043d0abcd13e5a/apps/meteor/server/api/v1/users.ts#L2041-L2077","documentation":"Thrown by POST /api/v1/users.setStatus when expiresAt is supplied but is not parseable as a date — new Date(expiresAt) yields NaN. It uses code error-invalid-date with method 'users.setStatus' and only checks this format problem; range (future) is a separate error.","triggerScenarios":"POST users.setStatus {\"status\":\"away\",\"expiresAt\":\"tomorrow\"}; numeric epoch seconds sent instead of an ISO-8601 string where the runtime parses it as invalid; localised date formats like 31/12/2026; trailing whitespace or BOM in the value.","commonSituations":"Client code formatting dates with locale-specific toString(); passing epoch seconds vs milliseconds confusion; strings from a form input never normalized.","solutions":["Send an ISO-8601 string: new Date(x).toISOString()","Validate with !Number.isNaN(Date.parse(expiresAt)) before calling","Pass milliseconds number instead of an ambiguous string if your client supports it","Strip/trim user-supplied date inputs"],"exampleFix":"// before\nawait sdk.post('users.setStatus', { status, expiresAt: '31/12/2026' });\n// after\nawait sdk.post('users.setStatus', { status, expiresAt: new Date('2026-12-31T00:00:00Z').toISOString() });","handlingStrategy":"validation","validationCode":"if (expiresAt != null && Number.isNaN(Date.parse(expiresAt))) throw new TypeError(`invalid expiresAt: ${expiresAt}`);\nawait sdk.post('users.setStatus', { status, message, expiresAt: expiresAt ? new Date(expiresAt).toISOString() : undefined });","typeGuard":"const isValidIsoDate = (v: unknown): v is string => typeof v === 'string' && !Number.isNaN(Date.parse(v));","tryCatchPattern":"try { await sdk.post('users.setStatus', body); } catch (e) { if (e.response?.data?.errorType === 'error-invalid-date' && /Invalid expiresAt/.test(e.response.data.message)) { body.expiresAt = new Date().toISOString(); await sdk.post('users.setStatus', body); } else throw e; }","preventionTips":["Always serialize dates with toISOString()","Date.parse-validate user input before sending","Decide epoch-seconds vs milliseconds convention once"],"tags":["rest-api","date-validation","status"],"backgroundTag":"invalid-date-format","analyzedSha":"e4b8178b205510181a96ceefee043d0abcd13e5a","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}