{"record":{"id":"6933544db48af33d","repo":"RocketChat/Rocket.Chat","slug":"invalid-token-693354","errorCode":null,"errorMessage":"invalid-token","messagePattern":"invalid-token","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/room.ts","lineNumber":77,"sourceCode":"\t\t\tintervalTimeInMS: 60000,\n\t\t},\n\t},\n\t{\n\t\tasync get() {\n\t\t\t// I'll temporary use check for validation, as validateParams doesnt support what's being done here\n\t\t\tconst extraCheckParams = onCheckRoomParams({\n\t\t\t\ttoken: String,\n\t\t\t\trid: Match.Maybe(String),\n\t\t\t\tagentId: Match.Maybe(String),\n\t\t\t});\n\n\t\t\tcheck(this.queryParams, extraCheckParams);\n\n\t\t\tconst { token, rid, agentId, ...extraParams } = this.queryParams;\n\n\t\t\tconst guest = token && (await findGuest(token));\n\t\t\tif (!guest) {\n\t\t\t\tthrow new Error('invalid-token');\n\t\t\t}\n\n\t\t\tif (!rid) {\n\t\t\t\tconst room = await LivechatRooms.findOneOpenByVisitorToken(token, {});\n\t\t\t\tif (room) {\n\t\t\t\t\treturn API.v1.success({ room, newRoom: false });\n\t\t\t\t}\n\n\t\t\t\tlet agent: SelectedAgent | undefined;\n\t\t\t\tconst agentObj = agentId && (await findAgent(agentId));\n\t\t\t\tif (agentObj) {\n\t\t\t\t\tif (isAgentWithInfo(agentObj)) {\n\t\t\t\t\t\tconst { username = undefined } = agentObj;\n\t\t\t\t\t\tagent = { agentId, username };\n\t\t\t\t\t} else {\n\t\t\t\t\t\tagent = { agentId };\n\t\t\t\t\t}\n\t\t\t\t}","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/room.ts#L59-L95","documentation":"Thrown in the GET handler of 'livechat/room' (room.ts:75-78) when the guest lookup fails. The expression is 'token && (await findGuest(token))' — if token is falsy (empty/undefined), the short-circuit yields the falsy token value; if token is truthy but findGuest returns null, guest is null. Either way, !guest triggers the throw.","triggerScenarios":"Calling GET /api/v1/livechat/room without a token query param, or with a token that doesn't match any visitor. The checkParams validation at line 71 requires token as a String, but if token is somehow empty or the visitor lookup fails, this fires.","commonSituations":"Token query param omitted from the GET request URL; token doesn't match a registered visitor; visitor was deleted; token from a different environment; stale/expired session token.","solutions":["Verify the token param is present in the query string: GET /api/v1/livechat/room?token=YOUR_TOKEN.","Verify the token matches a visitor: db.livechat_visitors.findOne({token: '<your-token>'}).","If no visitor exists, register one first via POST /api/v1/livechat/visitor."],"exampleFix":"// before\nGET /api/v1/livechat/room\n// throws 'invalid-token' — token missing or no visitor\n\n// after\nGET /api/v1/livechat/room?token=valid-visitor-token","handlingStrategy":"validation","validationCode":"// Verify token is present and valid before calling GET /livechat/room\nif (!token) {\n  throw new Error('token query param is required');\n}\nconst visitor = await LivechatVisitors.getVisitorByToken(token);\nif (!visitor) {\n  token = await registerNewVisitor();\n}","typeGuard":"function isValidVisitor(visitor: ILivechatVisitor | null): visitor is ILivechatVisitor {\n  return visitor !== null && typeof visitor.token === 'string' && typeof visitor._id === 'string';\n}","tryCatchPattern":"try {\n  await api.get(`/livechat/room?token=${token}`);\n} catch (err) {\n  if (err.message === 'invalid-token') {\n    token = await registerNewVisitor();\n    await api.get(`/livechat/room?token=${token}`);\n  }\n}","preventionTips":["Always include the token query parameter in GET /livechat/room requests.","Validate the token resolves to a visitor at application startup.","Store tokens in a persistent client-side store and validate them on session restore."],"tags":["omnichannel","visitor","token","authentication","room"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}