{"record":{"id":"d5c834457812c291","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-d5c834","errorCode":"error-invalid-user","errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/messages/deleteFileMessage.ts","lineNumber":24,"sourceCode":"import type { DeleteResult } from 'mongodb';\n\nimport { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';\nimport { FileUpload } from '../../lib/media/file-upload';\nimport { deleteMessageValidatingPermission } from '../../lib/messages/deleteMessage';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tdeleteFileMessage(fileID: string): Promise<void | DeleteResult>;\n\t}\n}\n\nMeteor.methods<ServerMethods>({\n\tasync deleteFileMessage(fileID) {\n\t\tmethodDeprecationLogger.method('deleteFileMessage', '9.0.0', '/v1/chat.delete');\n\t\tconst userId = Meteor.userId();\n\t\tif (!userId) {\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\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","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/messages/deleteFileMessage.ts#L6-L42","documentation":"Thrown by the 'deleteFileMessage' Meteor method when the calling connection has no authenticated user (Meteor.userId() === null). File deletion must be attributed to a user for permission checks, so the method aborts before even the check(fileID, String) runs. The deprecation logger points to /v1/chat.delete as the replacement.","triggerScenarios":"Meteor.call('deleteFileMessage', fileID) after the user's DDP session token expired or was revoked, or from an integration/bot that opened a DDP connection but never performed the login handshake.","commonSituations":"Stale tab after logout elsewhere; automated file-cleanup scripts using DDP without a login step; workspace reset wiped tokens while the client kept its stored resume token.","solutions":["Check Meteor.userId() before invoking; when null, re-authenticate and retry","For integrations, authenticate first (DDP login method) or switch to the REST endpoint /v1/chat.delete with an auth token","Centralize method calls in a wrapper that redirects to the login flow on 'error-invalid-user'"],"exampleFix":"// before\nMeteor.call('deleteFileMessage', fileID);\n\n// after\nif (!Meteor.userId()) {\n  // trigger re-login, then retry\n}\nMeteor.call('deleteFileMessage', fileID);","handlingStrategy":"validation","validationCode":"if (!Meteor.userId()) {\n  // re-run login flow instead of calling\n} else {\n  Meteor.call('deleteFileMessage', fileID);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await Meteor.callAsync('deleteFileMessage', fileID);\n} catch (e) {\n  if ((e as Meteor.Error).error === 'error-invalid-user') {\n    // force re-login; do not auto-retry in a loop\n  }\n}","preventionTips":["Gate destructive actions (delete) on an authenticated session check","Have integrations authenticate over DDP before issuing method calls, or use REST with tokens","Match on the error code 'error-invalid-user', never on the human-readable message"],"tags":["meteor","ddp","authentication","file-upload"],"backgroundTag":"user-not-authenticated","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}