RocketChat/Rocket.Chat · error · Error
Transfer to entity with id
Error message
Transfer to entity with id ${transferData.to} not found What it means
FileUpload.get resolves the serving handler from the upload record's store field (e.g. 'FileSystem:Uploads', 'S3:Avatars', 'Webdav:Uploads'). If no handler with that name is registered on this server (getStoreByName logs 'Upload handler does not exists' and returns undefined) or the handler has no get, it responds 404 — the file record exists, but this deployment cannot serve that store. Classic after storage-type changes without migrating files, or when a store's registering module is not loaded.
Solutions
- Keep the previous store handler available so old files remain servable (Rocket.Chat registers store classes regardless of the active type) or migrate file bytes to the active store
- Verify the module registering the missing store (config/FileSystem.ts, config/AmazonS3.ts, config/Webdav.ts) is actually loaded on this server
- Compare the file's store value against the registered handlers (a SystemLogger 'Upload handler does not exists' entry names the exact handlerName) and fix stale values on migration
- As a last resort, re-upload affected files or move them between stores programmatically
Example fix
// before
FileUpload.get(file, req, res, next); // 404 when store handler absent
// after: guard and report the migration gap
const store = FileUpload.getStoreByName(file.store);
if (!store?.get) {
SystemLogger.error({ msg: 'no handler for store', store: file.store, fileId: file._id });
return; // schedule migration instead of a bare 404
} Defensive patterns
Strategy: type-guard
Validate before calling
const handler = FileUpload.handlers[file.store as string];
if (!handler?.get) { /* this server cannot serve store ${file.store}: migrate or fix before calling FileUpload.get */ } Type guard
const isServableStore = (storeName?: string): boolean => { try { return typeof FileUpload.getStoreByName(storeName)?.get === 'function'; } catch { return false; } }; Prevention
- Before storage migrations, inventory distinct store values in the Uploads/Avatars collections and keep old handlers registered until files are moved
- Alert on SystemLogger 'Upload handler does not exists' entries — they name the exact missing handlerName
- Validate file.store values after restoring databases from other deployments
- Test downloads of pre-migration files after every storage-type change
When it happens
Trigger: file.store names a store this server never registered: storage type switched (e.g. FileSystem to Amazon S3) and the old store handler is unavailable; a DB restored from a deployment with different storage settings; store name typos in migrated data; a custom store module removed between versions.
Common situations: FileUpload storage migrations leaving old records unservable; environment drift between staging and production; upgrades that dropped store registrations; manual Mongo edits to upload documents.
Related errors
- auth option should be of the form "username:password"
- Not found
- The environmental variable
- Command does not exist in the system currently
- emoji-is-not-image
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/217264d0b2744db8.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/app/apps/server/bridges/listeners.ts:447
.executeListener(args.event, {
room: (await this.orch.getConverters().get('rooms').convertRoom(agentData.room)) as IAppsLivechatRoom,
agent: this.orch.getConverters().get('users').convertToApp(agentData.user),
});
case AppInterface.IPostLivechatRoomTransferred: {
const [transferData] = args.payload;
const converter = transferData.type === LivechatTransferEventType.AGENT ? 'users' : 'departments';
const room = await this.orch.getConverters().get('rooms').convertById(transferData.room);
const from = await this.orch.getConverters().get(converter).convertById(transferData.from);
const to = await this.orch.getConverters().get(converter).convertById(transferData.to);
if (!room) {
throw new Error(`Room with id ${transferData.room} not found`);
}
if (!to) {
throw new Error(`Transfer to entity with id ${transferData.to} not found`);
}
return this.orch
.getManager()
.getListenerManager()
.executeListener(args.event, {
room,
from: from as NonNullable<typeof from>, // type definition in the apps-engine seems to be incorrect
to,
type: transferData.type,
});
}
case AppInterface.IPostLivechatGuestSaved: {
const [visitorId] = args.payload;
const visitor = await this.orch.getConverters().get('visitors').convertById(visitorId);
if (!visitor) {View on GitHub (pinned to b2c16d5842)