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

  1. 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
  2. Verify the module registering the missing store (config/FileSystem.ts, config/AmazonS3.ts, config/Webdav.ts) is actually loaded on this server
  3. 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
  4. 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

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


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)