{"record":{"id":"f04219479c9807be","repo":"RocketChat/Rocket.Chat","slug":"missing-user-to-perform-the-upload-operation","errorCode":null,"errorMessage":"Missing user to perform the upload operation","messagePattern":"Missing user to perform the upload operation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/uploads.ts","lineNumber":49,"sourceCode":"\tprotected async getBuffer(upload: IUpload, appId: string): Promise<Buffer> {\n\t\tthis.orch.debugLog(`The App ${appId} is getting the upload: \"${upload.id}\"`);\n\n\t\tconst rocketChatUpload = this.orch.getConverters()?.get('uploads').convertToRocketChat(upload);\n\n\t\tconst result = await FileUpload.getBuffer(rocketChatUpload);\n\n\t\tif (!(result instanceof Buffer)) {\n\t\t\tthrow new Error('Unknown error');\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprotected async createUpload(details: IUploadDetails, buffer: Buffer, appId: string): Promise<IUpload> {\n\t\tthis.orch.debugLog(`The App ${appId} is creating an upload \"${details.name}\"`);\n\n\t\tif (!details.userId && !details.visitorToken) {\n\t\t\tthrow new Error('Missing user to perform the upload operation');\n\t\t}\n\n\t\tconst fileStore = FileUpload.getStore('Uploads');\n\n\t\tdetails.type = determineFileType(buffer, details.name);\n\n\t\tconst uploadedFile = await fileStore.insert(getUploadDetails(details), buffer);\n\t\tthis.orch.debugLog(`The App ${appId} has created an upload`, uploadedFile);\n\t\tif (details.visitorToken) {\n\t\t\tawait sendFileLivechatMessage({ roomId: details.rid, visitorToken: details.visitorToken, file: uploadedFile });\n\t\t} else {\n\t\t\tawait sendFileMessage(details.userId, { roomId: details.rid, file: uploadedFile });\n\t\t}\n\t\treturn this.orch.getConverters()?.get('uploads').convertToApp(uploadedFile);\n\t}\n}\n","sourceCodeStart":31,"sourceCodeEnd":66,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/bridges/uploads.ts#L31-L66","documentation":"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'.","triggerScenarios":"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).","commonSituations":"Apps posting generated files (reports, exports) to a room; livechat apps losing the visitor token mid-session; refactors renaming the owner fields.","solutions":["Set details.userId — most commonly the app's own user id.","For livechat files, forward the visitor token: details.visitorToken = session.visitor.token.","Validate the owner field at the boundary before building the upload."],"exampleFix":"// before\nconst details: IUploadDetails = { name, size, rid, type };\nawait createUpload(details, buffer, appId);\n\n// after\nconst appUser = await this.reader.getUserReader().getAppUser();\nconst details: IUploadDetails = { name, size, rid, type, userId: appUser?.id };\nawait createUpload(details, buffer, appId);","handlingStrategy":"validation","validationCode":"const hasOwner = (d: IUploadDetails): boolean => Boolean(d.userId || d.visitorToken);\nif (!hasOwner(details)) {\n  throw new Error('Upload details need userId or visitorToken');\n}","typeGuard":"const isOwnedUploadDetails = (d: IUploadDetails): boolean =>\n  Boolean(d.userId || d.visitorToken);","tryCatchPattern":null,"preventionTips":["Always set userId from the app user (or visitorToken in livechat) when constructing upload details.","Centralize upload-details construction in one helper so the owner is never forgotten."],"tags":["apps-engine","uploads","validation","ownership"],"backgroundTag":"missing-required-argument","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}