RocketChat/Rocket.Chat · error · Error
Invalid app user, cannot transfer
Error message
Invalid app user, cannot transfer
What it means
Thrown by AppLivechatBridge.transferVisitor when Users.findOneByAppId(appId) returns null. Every installed App has a provisioned system user (the app user) used as the transferredBy actor; if it cannot be found the transfer cannot proceed. This points at an App installation/provisioning problem rather than a transfer-input problem.
Source
Thrown at apps/meteor/app/apps/server/bridges/livechat.ts:269
shouldConsiderIdleAgent: settings.get<boolean>('Livechat_enabled_when_agent_idle'),
shouldConsiderOfflineAgent: settings.get<boolean>('Livechat_accept_chats_with_no_agents'),
});
return this.orch.getConverters()?.get('visitors').convertVisitor(livechatVisitor);
}
protected async transferVisitor(visitor: IVisitor, transferData: ILivechatTransferData, appId: string): Promise<boolean> {
this.orch.debugLog(`The App ${appId} is transfering a livechat.`);
if (!visitor) {
throw new Error('Invalid visitor, cannot transfer');
}
const { targetAgent, targetDepartment: departmentId, currentRoom } = transferData;
const appUser = await Users.findOneByAppId(appId, {});
if (!appUser) {
throw new Error('Invalid app user, cannot transfer');
}
const { _id, username, name, type } = appUser;
const transferredBy = {
_id,
username,
name,
type,
userType: 'user',
} as const;
let userId;
let transferredTo;
if (targetAgent?.id) {
transferredTo = await Users.findOneAgentById(targetAgent.id, {
projection: { _id: 1, username: 1, name: 1 },
});
if (!transferredTo) {View on GitHub (pinned to f9d3ec372b)
Solutions
- Reinstall or re-enable the App so its system user is reprovisioned.
- Confirm the App's system user exists in the Users collection (type 'app').
- Check the App lifecycle hooks ran on install (enableApp provisioning).
- Avoid manually deleting users whose type is 'app'.
Defensive patterns
Strategy: validation
Validate before calling
const appUser = await Users.findOneByAppId(appId, {});
if (!appUser) {
throw new Error(`App ${appId} is not provisioned (system user missing); reinstall the App`);
}
await app.getLivechatModifier().transferVisitor(visitor, transferData); Type guard
const isAppProvisioned = async (appId: string): Promise<boolean> =>
Boolean(await Users.findOneByAppId(appId, { projection: { _id: 1 } })); Try / catch
try {
return await app.getLivechatModifier().transferVisitor(visitor, transferData);
} catch (e) {
if ((e as Error).message === 'Invalid app user, cannot transfer') {
// prompt reinstall/re-enable of the App, then retry
}
throw e;
} Prevention
- Do not manually delete users whose type is 'app'.
- Reinstall/re-enable Apps to reprovision their system users.
- After a DB restore, verify App system users are present.
When it happens
Trigger: An App invokes the transfer accessor; the bridge looks up its own provisioned user via Users.findOneByAppId(appId) and gets null, e.g. the App's system user was deleted, the appId is stale, or provisioning did not complete.
Common situations: App's system user was removed manually or by a cleanup job; App was partially uninstalled/reinstalled and the user record is missing; appId mismatch after an App re-import; a DB restore that omitted the apps' user documents.
Related errors
- Invalid visitor, cannot transfer
- Invalid target agent, cannot transfer
- Room with id ${transferData.room} not found
- Transfer to entity with id ${transferData.to} not found
- Visitor with id ${visitorId} not found
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/5d95bb63a2866953.
Report an issue: GitHub.