RocketChat/Rocket.Chat · error · Meteor.Error
invalid-token
invalid-token
Error message
invalid-token
What it means
Thrown by GET /api/v1/livechat/visitor/:token (unauthenticated, used by the widget) when no visitor document matches the given token. The token identifies the visitor across sessions; if it was never registered (no prior POST /api/v1/livechat/visitor) or was deleted, the lookup returns nothing and the Meteor error 'invalid-token' is returned.
Solutions
- Register first: POST /api/v1/livechat/visitor with the token, then GET /api/v1/livechat/visitor/<token>
- On 400 invalid-token, regenerate a fresh token, register, and continue — treat it as 'unknown visitor'
- Make sure the token is persisted (localStorage) and identical (case, whitespace) on both calls
Defensive patterns
Strategy: validation
Validate before calling
const res = await fetch(`${server}/api/v1/livechat/visitor/${encodeURIComponent(token)}`);
if (res.status === 400) { // invalid-token: unknown token
await registerVisitor(token); // POST /api/v1/livechat/visitor
return fetch(`${server}/api/v1/livechat/visitor/${encodeURIComponent(token)}`);
} Try / catch
const body = await (await fetch(url)).json();
if (!body.success && body.error === 'invalid-token') { /* unknown visitor: register then retry, or treat as new session */ } Prevention
- Always POST (register) the token before GETting it
- Persist the token so return visitors keep their identity
- Treat invalid-token on GET as a benign 'not found', not a fatal error
When it happens
Trigger: Calling GET with a random/typo'd token; querying before registration completed; the visitor was deleted by DELETE /api/v1/livechat/visitor/:token (or GDPR cleanup) and the widget still holds the old token in localStorage.
Common situations: Widget state wiped or users switching browsers/devices where the stored token never existed on the server; test scripts that generate a token but never POST it; stale tokens after workspace data pruning.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- error-invalid-token
- error-livechat-visitor-registration
- Emoji not found.
- error-challenge-not-found
- error-invalid-contact
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/64e0f6b2ca67ddbc.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/api/v1/omnichannel/visitor.ts:112
if (!result) {
return API.v1.success({ visitor });
}
return API.v1.success({ visitor: await VisitorsRaw.findOneEnabledById(visitor._id) });
},
},
);
API.v1.addRoute('livechat/visitor/:token', {
async get() {
check(this.urlParams, {
token: String,
});
const visitor = await VisitorsRaw.getVisitorByToken(this.urlParams.token, {});
if (!visitor) {
throw new Meteor.Error('invalid-token');
}
return API.v1.success({ visitor });
},
async delete() {
check(this.urlParams, {
token: String,
});
const visitor = await VisitorsRaw.getVisitorByToken(this.urlParams.token, {});
if (!visitor) {
throw new Meteor.Error('invalid-token');
}
const extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}, { userId: this.userId });
const rooms = await LivechatRooms.findOpenByVisitorToken(
this.urlParams.token,
{
projection: {View on GitHub (pinned to b2c16d5842)