{"record":{"id":"0ab044328d63b963","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-0ab044","errorCode":"error-not-allowed","errorMessage":"Not allowed","messagePattern":"Not allowed","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/media/getS3FileUrl.ts","lineNumber":26,"sourceCode":"import { UploadFS } from '../../ufs';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tgetS3FileUrl(fileId: string): string;\n\t}\n}\n\nMeteor.methods<ServerMethods>({\n\tasync getS3FileUrl(fileId) {\n\t\tcheck(fileId, String);\n\t\tconst uid = Meteor.userId();\n\t\tif (settings.get<boolean>('FileUpload_ProtectFiles') && !uid) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'sendFileMessage' });\n\t\t}\n\t\tconst file = await Uploads.findOneById(fileId);\n\t\tif (!file?.rid) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed');\n\t\t}\n\t\tconst room = await Rooms.findOneById(file.rid);\n\t\tif (uid && room && !(await canAccessRoomAsync(room, { _id: uid }))) {\n\t\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed');\n\t\t}\n\n\t\treturn UploadFS.getStore('AmazonS3:Uploads').getRedirectURL(file);\n\t},\n});\n","sourceCodeStart":8,"sourceCodeEnd":36,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/media/getS3FileUrl.ts#L8-L36","documentation":"getS3FileUrl loads the upload via Uploads.findOneById(fileId) and throws error-not-allowed 'Not allowed' when the record is missing or has no rid — i.e. the file is not (yet) associated with any room. A second, later throw with the same code covers users who cannot access the file's room; this one at the rid check means the file itself is unusable for a redirect.","triggerScenarios":"Passing a fileId that does not exist, belongs to a different collection, or was captured mid-upload before the room association (rid) was written; file ids copied from third-party asset references rather than the upload record.","commonSituations":"Clients resolving URLs before the upload transaction finishes; stale ids after files were purged; using ids from Uploads records that never got tied to a room.","solutions":["Use the fileId exactly as returned by the completed upload (file record from the upload store), not a filename or external id","Wait for the upload to finish (rid persisted) before requesting the S3 redirect URL","If the record is gone, treat the file as deleted and stop resolving its URL"],"exampleFix":"// before\nconst url = await Meteor.callAsync('getS3FileUrl', fileId);\n\n// after: server-side pre-check that the upload is room-bound\nconst file = await Uploads.findOneById(fileId);\nif (!file?.rid) {\n  throw new Meteor.Error('error-not-allowed', 'File is missing or not attached to a room yet');\n}\nconst url = await Meteor.callAsync('getS3FileUrl', file._id);","handlingStrategy":"validation","validationCode":"// server-side: verify the upload record is room-bound before requesting the URL\nconst file = await Uploads.findOneById(fileId);\nif (!file?.rid) {\n  throw new Meteor.Error('error-not-allowed', 'File is missing or not attached to a room');\n}\nconst url = await Meteor.callAsync('getS3FileUrl', file._id);","typeGuard":"const isRoomBoundUpload = (f: { rid?: string } | null | undefined): f is { rid: string } =>\n  typeof f?.rid === 'string' && f.rid.length > 0;","tryCatchPattern":"try {\n  const url = await Meteor.callAsync('getS3FileUrl', fileId);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'error-not-allowed') {\n    // either no rid on the file or no access to its room: stop resolving the URL\n    return;\n  }\n  throw err;\n}","preventionTips":["Only request S3 URLs with the fileId returned by a completed upload","Wait until the upload record has its rid before generating links","Remember the same code also fires for users who cannot access the file's room"],"tags":["file-upload","s3","validation","meteor-methods"],"backgroundTag":"file-access-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}