RocketChat/Rocket.Chat · error · Error
Invalid token for livechat message
Error message
Invalid token for livechat message
What it means
Thrown by AppLivechatBridge.createMessage when the IAppsLivechatMessage passed by an App has no token property. The token ties a livechat message to its visitor/guest session; without it the omni-core sendMessage path cannot resolve the sender, so the bridge rejects the call before doing any work.
Source
Thrown at apps/meteor/app/apps/server/bridges/livechat.ts:57
constructor(private readonly orch: IAppServerOrchestrator) {
super();
}
protected isOnline(departmentId?: string): boolean {
// This function will be converted to sync inside the apps-engine code
// TODO: Track Deprecation
return deasyncPromise(online(departmentId));
}
protected async isOnlineAsync(departmentId?: string): Promise<boolean> {
return online(departmentId);
}
protected async createMessage(message: IAppsLivechatMessage, appId: string): Promise<string> {
this.orch.debugLog(`The App ${appId} is creating a new message.`);
if (!message.token) {
throw new Error('Invalid token for livechat message');
}
// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.
const guest = this.orch.getConverters().get('visitors').convertAppVisitor(message.visitor);
const appMessage = await this.orch.getConverters().get('messages').convertAppMessage(message);
const livechatMessage = appMessage as ILivechatMessage | undefined;
const msg = await sendMessage({
guest: guest as ILivechatVisitor,
message: livechatMessage as ILivechatMessage,
agent: undefined,
roomInfo: {
source: {
type: OmnichannelSourceType.APP,
id: appId,
alias: this.orch.getManager()?.getOneById(appId)?.getNameSlug(),
},
},View on GitHub (pinned to f9d3ec372b)
Solutions
- Set message.token to the visitor token before calling createMessage (typically read.app.getLivechatRead().getVisitor().token or the room's visitor token).
- When forwarding an existing livechat message, spread the original object so token is preserved.
- Add a unit test asserting token is present on every message handed to the creator.
- On apps-engine upgrades, re-check the IAppsLivechatMessage shape for token placement.
Example fix
// before
await app.getLivechatCreator().createMessage({
rid: room.id,
msg: 'hi',
visitor: livechatVisitor,
}); // missing token -> throws
// after
await app.getLivechatCreator().createMessage({
rid: room.id,
msg: 'hi',
token: livechatVisitor.token,
visitor: livechatVisitor,
}); Defensive patterns
Strategy: validation
Validate before calling
function assertLivechatMessageToken(message: IAppsLivechatMessage): void {
if (!message.token || typeof message.token !== 'string') {
throw new Error('IAppsLivechatMessage.token is required and must be a non-empty string');
}
}
assertLivechatMessageToken(message);
await app.getLivechatCreator().createMessage(message); Type guard
const hasLivechatToken = (m: IAppsLivechatMessage): m is IAppsLivechatMessage & { token: string } =>
typeof m.token === 'string' && m.token.length > 0; Try / catch
try {
await app.getLivechatCreator().createMessage(message);
} catch (e) {
if ((e as Error).message.includes('Invalid token')) {
// fix message.token and retry, or notify the user
}
throw e;
} Prevention
- Always copy visitor.token into the message before creating.
- Spread the original message when forwarding to avoid dropping token.
- Unit-test message construction to assert token presence.
When it happens
Trigger: An App calls the livechat message creator (e.g. app.getLivechatCreator().createMessage(msg)) with a message whose token is undefined, null, or empty string. The message object is constructed without copying the visitor token.
Common situations: App builds a new IAppsLivechatMessage from scratch and forgets to set token; App copies fields selectively and drops token; App receives a message via a read accessor, mutates it, and the token is lost through serialization; version mismatch where the apps-engine message shape no longer carries token at top level.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The agent with id "${agent.id}" was not found.
- Invalid agentId
- Invalid visitor, cannot transfer
- Invalid target agent, cannot transfer
- Invalid editor assigned to the message for the update.
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/3ae0f8ff5e3234f7.
Report an issue: GitHub.