RocketChat/Rocket.Chat · error

Missing user to perform the upload operation

Error message

Missing user to perform the upload operation

What it means

UploadsBridge.createUpload requires an owner: the details must carry either userId (a Rocket.Chat user, typically the app's bot user) or visitorToken (a livechat guest). With both absent the upload would have no author, so the bridge refuses with 'Missing user to perform the upload operation'.

Solutions

  1. Set details.userId — most commonly the app's own user id.
  2. For livechat files, forward the visitor token: details.visitorToken = session.visitor.token.
  3. Validate the owner field at the boundary before building the upload.

Example fix

// before
const details: IUploadDetails = { name, size, rid, type };
await createUpload(details, buffer, appId);

// after
const appUser = await this.reader.getUserReader().getAppUser();
const details: IUploadDetails = { name, size, rid, type, userId: appUser?.id };
await createUpload(details, buffer, appId);
Defensive patterns

Strategy: validation

Validate before calling

const hasOwner = (d: IUploadDetails): boolean => Boolean(d.userId || d.visitorToken);
if (!hasOwner(details)) {
  throw new Error('Upload details need userId or visitorToken');
}

Type guard

const isOwnedUploadDetails = (d: IUploadDetails): boolean =>
  Boolean(d.userId || d.visitorToken);

Prevention

When it happens

Trigger: App calls createUpload(details, buffer, appId) where details contains neither userId nor visitorToken — e.g. IUploadDetails built by hand without an owner, or using a wrong field name (user instead of userId, token instead of visitorToken).

Common situations: Apps posting generated files (reports, exports) to a room; livechat apps losing the visitor token mid-session; refactors renaming the owner fields.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/f04219479c9807be. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/app/apps/server/bridges/uploads.ts:49

	protected async getBuffer(upload: IUpload, appId: string): Promise<Buffer> {
		this.orch.debugLog(`The App ${appId} is getting the upload: "${upload.id}"`);

		const rocketChatUpload = this.orch.getConverters()?.get('uploads').convertToRocketChat(upload);

		const result = await FileUpload.getBuffer(rocketChatUpload);

		if (!(result instanceof Buffer)) {
			throw new Error('Unknown error');
		}

		return result;
	}

	protected async createUpload(details: IUploadDetails, buffer: Buffer, appId: string): Promise<IUpload> {
		this.orch.debugLog(`The App ${appId} is creating an upload "${details.name}"`);

		if (!details.userId && !details.visitorToken) {
			throw new Error('Missing user to perform the upload operation');
		}

		const fileStore = FileUpload.getStore('Uploads');

		details.type = determineFileType(buffer, details.name);

		const uploadedFile = await fileStore.insert(getUploadDetails(details), buffer);
		this.orch.debugLog(`The App ${appId} has created an upload`, uploadedFile);
		if (details.visitorToken) {
			await sendFileLivechatMessage({ roomId: details.rid, visitorToken: details.visitorToken, file: uploadedFile });
		} else {
			await sendFileMessage(details.userId, { roomId: details.rid, file: uploadedFile });
		}
		return this.orch.getConverters()?.get('uploads').convertToApp(uploadedFile);
	}
}

View on GitHub (pinned to b2c16d5842)