{"record":{"id":"7075f5dc2cd7de89","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-file","errorCode":"error-invalid-file","errorMessage":"Invalid file","messagePattern":"Invalid file","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/messages/deleteFileMessage.ts","lineNumber":45,"sourceCode":"\t\t}\n\t\tcheck(fileID, String);\n\n\t\tconst msg = await Messages.getMessageByFileId(fileID);\n\n\t\tif (msg) {\n\t\t\treturn deleteMessageValidatingPermission(msg, userId);\n\t\t}\n\n\t\tconst user = await Users.findOneById(userId, { projection: { username: 1 } });\n\t\tif (!user) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', {\n\t\t\t\tmethod: 'deleteFileMessage',\n\t\t\t});\n\t\t}\n\n\t\tconst file = await Uploads.findOneById(fileID, { projection: { userId: 1, rid: 1, expiresAt: 1, uploadedAt: 1 } });\n\t\tif (!file) {\n\t\t\tthrow new Meteor.Error('error-invalid-file', 'Invalid file', {\n\t\t\t\tmethod: 'deleteFileMessage',\n\t\t\t});\n\t\t}\n\n\t\tif (!(await Upload.canDeleteFile(user, file, null))) {\n\t\t\tthrow new Meteor.Error('error-not-authorized', 'Not authorized', {\n\t\t\t\tmethod: 'deleteFileMessage',\n\t\t\t});\n\t\t}\n\n\t\treturn FileUpload.getStore('Uploads').deleteById(fileID);\n\t},\n});\n","sourceCodeStart":27,"sourceCodeEnd":59,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/messages/deleteFileMessage.ts#L27-L59","documentation":"Thrown when Uploads.findOneById(fileID) returns null: no Uploads document exists for the given id. By this point the method already established that no message references the file and that the caller is a valid user; the missing Uploads record is what fails. Deletion via this method only works for files tracked in the Uploads collection.","triggerScenarios":"Meteor.call('deleteFileMessage', fileID) with a mistyped id, a file whose Uploads record was already removed (earlier delete partially completed), or a file id copied from a different database/workspace.","commonSituations":"Double-click / double-submission of a delete button (second call finds nothing); ids transplanted between environments; Uploads and the GridFS store out of sync after an interrupted delete or partial migration.","solutions":["Re-verify the file id against a current Uploads record (refresh the file list) before deleting","Make the flow idempotent: on 'error-invalid-file' during a retry, treat the file as already deleted and refresh UI state","If Uploads records and the physical store disagree, reconcile the Uploads collection with the store (the standard delete path removes derivatives like thumbnails too)","Prefer the supported REST path /v1/chat.delete for message-bound deletions"],"exampleFix":"// before\nawait Meteor.callAsync('deleteFileMessage', fileID);\n\n// after — tolerate already-deleted files\ntry {\n  await Meteor.callAsync('deleteFileMessage', fileID);\n} catch (e) {\n  if (e.error === 'error-invalid-file') {\n    // already gone: update local state as deleted, do not retry\n  } else {\n    throw e;\n  }\n}","handlingStrategy":"try-catch","validationCode":"const file = message?.files?.find((f) => f._id === fileID);\nif (!file) {\n  // id not referenced by any known message: refresh data before deleting\n  return;\n}\nMeteor.call('deleteFileMessage', fileID);","typeGuard":null,"tryCatchPattern":"try {\n  await Meteor.callAsync('deleteFileMessage', fileID);\n} catch (e) {\n  if ((e as Meteor.Error).error === 'error-invalid-file') {\n    // already deleted / unknown id: mark as removed locally, stop retrying\n  } else {\n    throw e;\n  }\n}","preventionTips":["Single-flight the delete action so the same id cannot be submitted twice concurrently","Pass ids straight from server payloads without manual transformation","Treat delete as idempotent in the UI: absorb 'error-invalid-file' on retry"],"tags":["meteor","file-upload","uploads-collection","resource-not-found"],"backgroundTag":"resource-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}