{"record":{"id":"3ae0f8ff5e3234f7","repo":"RocketChat/Rocket.Chat","slug":"invalid-token-for-livechat-message","errorCode":null,"errorMessage":"Invalid token for livechat message","messagePattern":"Invalid token for livechat message","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/livechat.ts","lineNumber":57,"sourceCode":"\tconstructor(private readonly orch: IAppServerOrchestrator) {\n\t\tsuper();\n\t}\n\n\tprotected isOnline(departmentId?: string): boolean {\n\t\t// This function will be converted to sync inside the apps-engine code\n\t\t// TODO: Track Deprecation\n\t\treturn deasyncPromise(online(departmentId));\n\t}\n\n\tprotected async isOnlineAsync(departmentId?: string): Promise<boolean> {\n\t\treturn online(departmentId);\n\t}\n\n\tprotected async createMessage(message: IAppsLivechatMessage, appId: string): Promise<string> {\n\t\tthis.orch.debugLog(`The App ${appId} is creating a new message.`);\n\n\t\tif (!message.token) {\n\t\t\tthrow new Error('Invalid token for livechat message');\n\t\t}\n\n\t\t// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.\n\t\tconst guest = this.orch.getConverters().get('visitors').convertAppVisitor(message.visitor);\n\t\tconst appMessage = await this.orch.getConverters().get('messages').convertAppMessage(message);\n\t\tconst livechatMessage = appMessage as ILivechatMessage | undefined;\n\n\t\tconst msg = await sendMessage({\n\t\t\tguest: guest as ILivechatVisitor,\n\t\t\tmessage: livechatMessage as ILivechatMessage,\n\t\t\tagent: undefined,\n\t\t\troomInfo: {\n\t\t\t\tsource: {\n\t\t\t\t\ttype: OmnichannelSourceType.APP,\n\t\t\t\t\tid: appId,\n\t\t\t\t\talias: this.orch.getManager()?.getOneById(appId)?.getNameSlug(),\n\t\t\t\t},\n\t\t\t},","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/livechat.ts#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait app.getLivechatCreator().createMessage({\n  rid: room.id,\n  msg: 'hi',\n  visitor: livechatVisitor,\n}); // missing token -> throws\n\n// after\nawait app.getLivechatCreator().createMessage({\n  rid: room.id,\n  msg: 'hi',\n  token: livechatVisitor.token,\n  visitor: livechatVisitor,\n});","handlingStrategy":"validation","validationCode":"function assertLivechatMessageToken(message: IAppsLivechatMessage): void {\n  if (!message.token || typeof message.token !== 'string') {\n    throw new Error('IAppsLivechatMessage.token is required and must be a non-empty string');\n  }\n}\nassertLivechatMessageToken(message);\nawait app.getLivechatCreator().createMessage(message);","typeGuard":"const hasLivechatToken = (m: IAppsLivechatMessage): m is IAppsLivechatMessage & { token: string } =>\n  typeof m.token === 'string' && m.token.length > 0;","tryCatchPattern":"try {\n  await app.getLivechatCreator().createMessage(message);\n} catch (e) {\n  if ((e as Error).message.includes('Invalid token')) {\n    // fix message.token and retry, or notify the user\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["apps-engine","livechat","message","validation","visitor-token"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}