{"record":{"id":"d59a0005136e3ccb","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-d59a00","errorCode":"error-invalid-user","errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/rooms/archiveRoom.ts","lineNumber":25,"sourceCode":"import { RoomMemberActions } from '../../../definition/IRoomTypeConfig';\nimport { hasPermissionAsync } from '../../lib/authorization/hasPermission';\nimport { methodDeprecationLogger } from '../../lib/deprecationWarningLogger';\nimport { archiveRoom } from '../../lib/rooms/archiveRoom';\nimport { roomCoordinator } from '../../lib/rooms/roomCoordinator';\n\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tarchiveRoom(rid: string): Promise<void>;\n\t}\n}\n\nexport const executeArchiveRoom = async (userId: string, rid: string) => {\n\tcheck(rid, String);\n\n\tconst user = await Users.findOneById(userId, { projection: { username: 1, name: 1 } });\n\tif (!user || !isRegisterUser(user)) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'archiveRoom' });\n\t}\n\n\tconst room = await Rooms.findOneById(rid);\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'archiveRoom' });\n\t}\n\n\tif (!(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId))) {\n\t\tthrow new Meteor.Error('error-direct-message-room', `rooms type: ${room.t} can not be archived`, { method: 'archiveRoom' });\n\t}\n\n\tif (!(await hasPermissionAsync(userId, 'archive-room', room._id))) {\n\t\tthrow new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'archiveRoom' });\n\t}\n\n\treturn archiveRoom(rid, user);\n};\n","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/archiveRoom.ts#L7-L43","documentation":"Thrown by executeArchiveRoom when the acting user cannot be used for archiving: Users.findOneById(userId) found no document, or the document fails isRegisterUser (not a plain active registered user, e.g. app/bot or deactivated accounts). Rocket.Chat requires a registered user because that user is recorded as archiving the room. The DDP wrapper has already confirmed a logged-in connection before calling this helper, so hitting this line means the account behind the session is missing or not a regular registered user.","triggerScenarios":"Calling Meteor.call('archiveRoom', rid) while the acting account was deleted or deactivated after login; server-side reuse of executeArchiveRoom(userId, rid) with a nonexistent or app/bot user _id; test fixtures that insert users without the active/type fields isRegisterUser requires.","commonSituations":"Custom integrations passing an app or system user id; admin deactivating a user while their session is still alive; LDAP/OAuth accounts disabled upstream but sessions not purged; unit tests seeding bare user records.","solutions":["Verify the acting account first: it must exist and satisfy isRegisterUser (plain user type, active).","If the session went stale, log out and back in so the connection carries a fresh, valid userId.","Replace the deprecated DDP method with POST /api/v1/channels.archive using valid X-Auth-Token/X-User-Id headers."],"exampleFix":"// before\nawait executeArchiveRoom(appUserId, rid); // appUserId belongs to an app/bot account\n\n// after\nconst user = await Users.findOneById(userId, { projections: { type: 1, active: 1 } });\nif (!user || !isRegisterUser(user)) {\n  throw new Error('Acting user is not a registered user');\n}\nawait executeArchiveRoom(userId, rid);","handlingStrategy":"try-catch","validationCode":"const me = Meteor.user();\nif (!me) {\n  // no account on this connection - re-login before calling archiveRoom\n}","typeGuard":"const isRegisteredAccount = (u: { type?: string; active?: boolean } | null | undefined): u is { type: string; active: boolean } =>\n  !!u && u.type === 'user' && u.active === true;","tryCatchPattern":"try {\n  await Meteor.callAsync('archiveRoom', rid);\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {\n    // account missing or not registered: end the session and re-authenticate\n    await Meteor.logout();\n    goToLogin();\n    return;\n  }\n  throw e;\n}","preventionTips":["Always derive the acting user from Meteor.userId() on a live connection instead of passing stored ids.","Never use app/bot or system accounts for member actions like archiveRoom; use a registered human account or the REST API.","Treat error-invalid-user arriving after a previously valid session as an account problem, not a transient glitch - verify with users.info."],"tags":["rocket-chat","meteor","ddp","archive-room","user-validation","authentication"],"backgroundTag":"meteor-invalid-user","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}