{"record":{"id":"303991a4b8371638","repo":"RocketChat/Rocket.Chat","slug":"error-invite-expired","errorCode":"error-invite-expired","errorMessage":"The invite token has expired.","messagePattern":"The invite token has expired\\.","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/rooms/invites/validateInviteToken.ts","lineNumber":38,"sourceCode":"\t}\n\n\tconst room = await Rooms.findOneById(inviteData.rid);\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'The invite token is invalid.', {\n\t\t\tmethod: 'validateInviteToken',\n\t\t\tfield: 'rid',\n\t\t});\n\t}\n\n\tif (settings.get('ABAC_Enabled') && room?.abacAttributes?.length) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Room is ABAC managed', {\n\t\t\tmethod: 'validateInviteToken',\n\t\t\tfield: 'rid',\n\t\t});\n\t}\n\n\tif (inviteData.expires && new Date(inviteData.expires).getTime() <= Date.now()) {\n\t\tthrow new Meteor.Error('error-invite-expired', 'The invite token has expired.', {\n\t\t\tmethod: 'validateInviteToken',\n\t\t\tfield: 'expires',\n\t\t});\n\t}\n\n\tif (inviteData.maxUses > 0 && inviteData.uses >= inviteData.maxUses) {\n\t\tthrow new Meteor.Error('error-invite-expired', 'The invite token has expired.', {\n\t\t\tmethod: 'validateInviteToken',\n\t\t\tfield: 'maxUses',\n\t\t});\n\t}\n\n\treturn {\n\t\tinviteData,\n\t\troom,\n\t};\n};\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/rooms/invites/validateInviteToken.ts#L20-L56","documentation":"Thrown by validateInviteToken when inviteData.expires is set and its timestamp is <= Date.now() (validateInviteToken.ts:38). This is the time-based half of invite expiry; details { field: 'expires' } distinguish it from the usage-limit case. The comparison is wall-clock, so server clock skew matters.","triggerScenarios":"An invite created with a finite expiration (days setting) whose deadline has passed; server clock drifted forward making fresh invites appear expired; long-lived invite links in documentation that outlived their expires value.","commonSituations":"Admin created a 1-day invite and the user clicks it on day 2; NTP misconfiguration on the server; invites generated during testing kept being reused after their window closed.","solutions":["Have a room admin generate a new invite (or one with a longer/no expiration)","Verify server time (date, NTP status) if seemingly fresh invites are rejected","Pre-check server-side: if inviteData.expires && new Date(inviteData.expires).getTime() <= Date.now(), skip the call and surface a friendly 'link expired' message","Use details.field === 'expires' to differentiate from 'maxUses' exhaustion"],"exampleFix":"// before\nconst { inviteData, room } = await validateInviteToken(token);\n\n// after\nconst inviteData = await Invites.findOneById(token);\nif (inviteData?.expires && new Date(inviteData.expires).getTime() <= Date.now()) {\n\tthrow new Meteor.Error('error-invite-expired', 'This invite link has expired. Ask for a new one.');\n}\nconst { inviteData: valid, room } = await validateInviteToken(token);","handlingStrategy":"validation","validationCode":"const invite = await Invites.findOneById(token);\nif (invite?.expires && new Date(invite.expires).getTime() <= Date.now()) {\n\tthrow new Meteor.Error('error-invite-expired', 'This invite link has expired — ask for a new one');\n}\nconst result = await validateInviteToken(token);","typeGuard":null,"tryCatchPattern":"try {\n\tawait validateInviteToken(token);\n} catch (e) {\n\tif (e instanceof Meteor.Error && e.error === 'error-invite-expired' && e.details?.field === 'expires') {\n\t\t// time-based expiry: prompt for a fresh invite\n\t}\n}","preventionTips":["Keep server clocks NTP-synced so fresh invites are not falsely expired","Default new invites to sensible expirations; avoid very short windows for widely shared links","Branch on details.field ('expires' vs 'maxUses') instead of the shared message"],"tags":["invite","expiration","time","meteor"],"backgroundTag":"invite-token-expired","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}