RocketChat/Rocket.Chat · error · Error

invalid-token

invalid-token

Error message

invalid-token

What it means

Thrown by GET /api/v1/livechat/agent.info/:rid/:token when findGuest(token) returns null. findGuest calls LivechatVisitors.getVisitorByToken(token), so this error means no livechat visitor matches the provided token. The token is a URL path parameter identifying the livechat guest session.

Source

Thrown at apps/meteor/server/api/v1/omnichannel/agent.ts:28

	validateForbiddenErrorResponse,
	validateUnauthorizedErrorResponse,
} from '@rocket.chat/rest-typings';

import { API } from '../..';
import { findRoom, findGuest, findAgent, findOpenRoom } from './lib/livechat';
import { hasPermissionAsync } from '../../../lib/authorization/hasPermission';
import { hasRoleAsync } from '../../../lib/authorization/hasRole';
import { RoutingManager } from '../../../lib/omnichannel/RoutingManager';
import { getRequiredDepartment } from '../../../lib/omnichannel/departmentsLib';
import { saveAgentInfo } from '../../../lib/omnichannel/omni-users';
import { setUserStatusLivechat, allowAgentChangeServiceStatus } from '../../../lib/omnichannel/utils';
import type { ExtractRoutesFromAPI } from '../../ApiClass';

API.v1.addRoute('livechat/agent.info/:rid/:token', {
	async get() {
		const visitor = await findGuest(this.urlParams.token);
		if (!visitor) {
			throw new Error('invalid-token');
		}

		const room = await findRoom(this.urlParams.token, this.urlParams.rid);
		if (!room) {
			throw new Error('invalid-room');
		}

		const agent = room?.servedBy && (await findAgent(room.servedBy._id));
		if (!agent) {
			throw new Error('invalid-agent');
		}

		return API.v1.success({ agent });
	},
});

API.v1.addRoute(
	'livechat/agent.next/:token',

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Verify the token is correct and was issued by this server instance.
  2. If the visitor no longer exists, register a new livechat guest via POST /api/v1/livechat/visitor to obtain a fresh token.
  3. Check the LivechatVisitors collection for the token to confirm it exists.

Example fix

// before: using a stale/unknown token
GET /api/v1/livechat/agent.info/ROOM_ID/old-or-wrong-token
// after: obtain a valid token first
POST /api/v1/livechat/visitor { "visitor": { "name": "Guest", "token": "new-unique-token" } }
// then use the token
GET /api/v1/livechat/agent.info/ROOM_ID/new-unique-token
Defensive patterns

Strategy: validation

Validate before calling

// Validate the visitor token exists before calling agent.info
async function isValidVisitorToken(baseUrl, token) {
  // Use the livechat visitor endpoint to verify
  const res = await fetch(`${baseUrl}/api/v1/livechat/visitor/${token}`);
  return res.ok;
}

if (!(await isValidVisitorToken(baseUrl, token))) {
  throw new Error('Invalid visitor token — register a new guest first');
}

Type guard

function isValidVisitorTokenFormat(token: unknown): token is string {
  return typeof token === 'string' && token.length > 0;
}

Try / catch

try {
  await getAgentInfo(rid, token);
} catch (e) {
  if (e.error === 'invalid-token' || e.message === 'invalid-token') {
    // Register a new visitor and retry
    const newToken = await registerLivechatVisitor();
    return getAgentInfo(rid, newToken);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling agent.info with a visitor token that does not exist in the LivechatVisitors collection — the token was never issued, was for a different server instance, or the visitor record was deleted.

Common situations: Stale token from a previous server instance before migration; visitor record purged by a retention/cleanup job; typo in the token; token from a test environment used against production.

Related errors


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