{"record":{"id":"6933544db48af33d","repo":"RocketChat/Rocket.Chat","slug":"invalid-token-693354","errorCode":null,"errorMessage":"invalid-token","messagePattern":"invalid-token","errorType":"exception","errorClass":"Error","httpStatus":400,"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/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/v1/omnichannel/room.ts#L59-L95","documentation":"Thrown by GET /api/v1/livechat/room when the visitor lookup fails. Because the handler first runs check(this.queryParams, { token: String, rid: Match.Maybe(String), ... }) (extensible via the onCheckRoomParams patch point), a missing token raises a Match validation error instead — so 'invalid-token' here means the token value matched no LivechatVisitors document, or an injected onCheckRoomParams hook made token optional.","triggerScenarios":"GET /api/v1/livechat/room?token=<unknown> (optionally &rid=&agentId=). Known trigger sub-case: relying on this endpoint to auto-create a room but passing a token that was never registered.","commonSituations":"Integration calls livechat/room before registering the visitor — the endpoint does NOT register visitors (unlike livechat/messages); widget token lost from storage; Apps/custom code extending onCheckRoomParams loosening the token requirement and hitting the null path.","solutions":["Register the visitor first (POST /api/v1/livechat/visitor) or let the widget's registration flow complete, then call livechat/room with the issued token.","Confirm the token survives storage round-trips (no whitespace/newlines) and matches the environment.","If you extended onCheckRoomParams, keep token required in the Match pattern so missing tokens fail validation with a clearer message."],"exampleFix":"// before (room requested with a fabricated token)\nawait fetch(`/api/v1/livechat/room?token=my-invented-token`);\n\n// after (register visitor, then create/obtain the room)\nconst v = await (await fetch('/api/v1/livechat/visitor', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ visitor: { token: 'tkn1', name: 'Lead' } }) })).json();\nawait fetch(`/api/v1/livechat/room?token=${v.visitor.token}`);","handlingStrategy":"validation","validationCode":"// livechat/room does NOT register visitors — register first\nawait ensureRegisteredVisitor({ token });\nconst res = await fetch(`/api/v1/livechat/room?token=${encodeURIComponent(token)}`);","typeGuard":null,"tryCatchPattern":"if (isLivechatErrorResponse(body) && body.error === 'invalid-token') {\n  await ensureRegisteredVisitor({ token }); // register then retry room creation once\n}","preventionTips":["Never assume livechat/room auto-creates visitors; only livechat/messages does fallback registration.","Keep the registration and room-open calls sequenced in an onboarding flow."],"tags":["livechat","omnichannel","visitor-token","room-creation","rest-api"],"backgroundTag":"invalid-auth-token","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"}