{"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":"Error","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/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/uploads.ts#L31-L66","documentation":"Thrown by createUpload when the IUploadDetails has neither a userId nor a visitorToken. Every uploaded file must be attributed to either a logged-in user or a livechat visitor, so the bridge rejects details that lack both identity anchors before touching the Uploads store.","triggerScenarios":"App calls createUpload with a details object where both userId and visitorToken are undefined/empty. This happens when the app builds details from a context that had no actor (e.g. a webhook-triggered flow with no impersonation).","commonSituations":"App author forgets to set the actor; event payload that triggered the upload had no sender; livechat integration passes room id but omits the visitor token; testing without a user context.","solutions":["Always set either details.userId (for normal users) or details.visitorToken (for livechat visitors) before creating the upload.","Derive the actor from the incoming message/event that triggered the upload.","Validate the details object with a guard before calling createUpload."],"exampleFix":"// before\nawait modify.getUploader().upload({ name, size, rid });\n\n// after\nif (!details.userId && !details.visitorToken) {\n  throw new Error('Cannot upload without an owning user or visitor');\n}\nawait modify.getUploader().upload({ name, size, rid, userId: sender.id });","handlingStrategy":"validation","validationCode":"if (!details.userId && !details.visitorToken) {\n  throw new Error('Upload requires a userId or visitorToken');\n}","typeGuard":"function hasUploadOwner(d: IUploadDetails): boolean {\n  return Boolean(d.userId || d.visitorToken);\n}","tryCatchPattern":null,"preventionTips":["Always attribute uploads to a user or livechat visitor.","Derive the owner from the triggering message/event.","Guard the details object before calling createUpload."],"tags":["apps-engine","uploads","validation","user-identity"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}