{"record":{"id":"29599cebee7e5aa7","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-token-29599c","errorCode":"error-invalid-token","errorMessage":"The invite token is invalid.","messagePattern":"The invite token is invalid\\.","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/rooms/invites/validateInviteToken.ts","lineNumber":8,"sourceCode":"import { Invites, Rooms } from '@rocket.chat/models';\nimport { Meteor } from 'meteor/meteor';\n\nimport { settings } from '../../../settings';\n\nexport const validateInviteToken = async (token: string) => {\n\tif (!token || typeof token !== 'string') {\n\t\tthrow new Meteor.Error('error-invalid-token', 'The invite token is invalid.', {\n\t\t\tmethod: 'validateInviteToken',\n\t\t\tfield: 'token',\n\t\t});\n\t}\n\n\tconst inviteData = await Invites.findOneById(token);\n\tif (!inviteData) {\n\t\tthrow new Meteor.Error('error-invalid-token', 'The invite token is invalid.', {\n\t\t\tmethod: 'validateInviteToken',\n\t\t\tfield: 'token',\n\t\t});\n\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',","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/rooms/invites/validateInviteToken.ts#L1-L26","documentation":"Thrown by validateInviteToken (apps/meteor/server/lib/rooms/invites/validateInviteToken.ts:8) as the very first guard: the token argument is falsy or not a string, so no database lookup has even happened. It uses code 'error-invalid-token' with details { method: 'validateInviteToken', field: 'token' }. This is a caller-side bug (missing/mistyped argument), not a stale invite.","triggerScenarios":"Calling validateInviteToken(''), validateInviteToken(undefined as any), or with a number/object; e.g. passing a URL query param that was never read, or passing the whole invite document instead of its _id string.","commonSituations":"Invite hash extracted from a URL path/query arrives undefined after a refactor; form field for the token was left empty; token variable shadowed or renamed during migration from callback to async code.","solutions":["Pass the invite's _id exactly as stored in the Invites collection (e.g. the token segment of an /invite/<token> link)","Guard at the call site: only call when typeof token === 'string' && token.trim().length > 0","If the token comes from a URL, decodeURIComponent and trim it before calling","Inspect error.details.field === 'token' to distinguish this argument bug from a not-found invite"],"exampleFix":"// before\nconst { inviteData, room } = await validateInviteToken(token);\n\n// after\nif (typeof token !== 'string' || token.trim().length === 0) {\n\tthrow new Meteor.Error('error-invalid-token', 'The invite token is invalid.', { method: 'validateInviteToken', field: 'token' });\n}\nconst { inviteData, room } = await validateInviteToken(token);","handlingStrategy":"type-guard","validationCode":"const token = typeof input?.token === 'string' ? input.token.trim() : '';\nif (token.length === 0) {\n\tthrow new Error('Invite token missing — provide the token segment of the invite link');\n}\nconst { inviteData, room } = await validateInviteToken(token);","typeGuard":"const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Normalize tokens once at the boundary: decodeURIComponent + trim","Type the parameter as string in your wrapper so undefined fails at compile time","Never pass the invite object — pass its _id"],"tags":["invite","token","argument-validation","meteor"],"backgroundTag":"invite-token-invalid","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}