RocketChat/Rocket.Chat · error · Error

invalid-token

Error message

invalid-token

What it means

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.

Source

Thrown at apps/meteor/server/api/v1/omnichannel/room.ts:77

			intervalTimeInMS: 60000,
		},
	},
	{
		async get() {
			// I'll temporary use check for validation, as validateParams doesnt support what's being done here
			const extraCheckParams = onCheckRoomParams({
				token: String,
				rid: Match.Maybe(String),
				agentId: Match.Maybe(String),
			});

			check(this.queryParams, extraCheckParams);

			const { token, rid, agentId, ...extraParams } = this.queryParams;

			const guest = token && (await findGuest(token));
			if (!guest) {
				throw new Error('invalid-token');
			}

			if (!rid) {
				const room = await LivechatRooms.findOneOpenByVisitorToken(token, {});
				if (room) {
					return API.v1.success({ room, newRoom: false });
				}

				let agent: SelectedAgent | undefined;
				const agentObj = agentId && (await findAgent(agentId));
				if (agentObj) {
					if (isAgentWithInfo(agentObj)) {
						const { username = undefined } = agentObj;
						agent = { agentId, username };
					} else {
						agent = { agentId };
					}
				}

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Verify the token param is present in the query string: GET /api/v1/livechat/room?token=YOUR_TOKEN.
  2. Verify the token matches a visitor: db.livechat_visitors.findOne({token: '<your-token>'}).
  3. If no visitor exists, register one first via POST /api/v1/livechat/visitor.

Example fix

// before
GET /api/v1/livechat/room
// throws 'invalid-token' — token missing or no visitor

// after
GET /api/v1/livechat/room?token=valid-visitor-token
Defensive patterns

Strategy: validation

Validate before calling

// Verify token is present and valid before calling GET /livechat/room
if (!token) {
  throw new Error('token query param is required');
}
const visitor = await LivechatVisitors.getVisitorByToken(token);
if (!visitor) {
  token = await registerNewVisitor();
}

Type guard

function isValidVisitor(visitor: ILivechatVisitor | null): visitor is ILivechatVisitor {
  return visitor !== null && typeof visitor.token === 'string' && typeof visitor._id === 'string';
}

Try / catch

try {
  await api.get(`/livechat/room?token=${token}`);
} catch (err) {
  if (err.message === 'invalid-token') {
    token = await registerNewVisitor();
    await api.get(`/livechat/room?token=${token}`);
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/6933544db48af33d. Report an issue: GitHub.