{"record":{"id":"d8789ebc64fd5197","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-d8789e","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/rooms/removeRoomOwner.ts","lineNumber":41,"sourceCode":"\tcheck(rid, String);\n\tcheck(userId, String);\n\n\tconst room = await Rooms.findOneById(rid, { projection: { t: 1, federated: 1, federation: 1 } });\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\tmethod: 'removeRoomOwner',\n\t\t});\n\t}\n\n\tif (!(await hasPermissionAsync(fromUserId, 'set-owner', rid)) && !isRoomFederated(room)) {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', {\n\t\t\tmethod: 'removeRoomOwner',\n\t\t});\n\t}\n\n\tconst user = await Users.findOneById(userId);\n\tif (!user?.username) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', {\n\t\t\tmethod: 'removeRoomOwner',\n\t\t});\n\t}\n\n\tconst subscription = await Subscriptions.findOneByRoomIdAndUserId(rid, user._id);\n\n\tif (!subscription) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\tmethod: 'removeRoomOwner',\n\t\t});\n\t}\n\n\tif (Array.isArray(subscription.roles) === false || subscription.roles?.includes('owner') === false) {\n\t\tthrow new Meteor.Error('error-user-not-owner', 'User is not an owner', {\n\t\t\tmethod: 'removeRoomOwner',\n\t\t});\n\t}\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/removeRoomOwner.ts#L23-L59","documentation":"removeRoomOwner loads the target with Users.findOneById(userId) and requires a non-empty username; throws error-invalid-user when the target does not exist or has no username. The userId argument must be the user's _id — passing a username here will always fail this lookup.","triggerScenarios":"Passing the target's username rather than _id as the second argument; target deleted before the call landed; user record without a username.","commonSituations":"Member-management UIs keyed by username; target account removed while an admin had the role dialog open.","solutions":["Resolve the target's _id (Users.findOneByUsername, or GET /api/v1/users.info?username=) before calling","Validate that the user exists and has a username before offering owner-removal actions","Drop stale targets from pickers when lookup fails"],"exampleFix":"// before\nawait Meteor.callAsync('removeRoomOwner', rid, targetUsername);\n\n// after\nconst user = Users.findOne({ username: targetUsername });\nif (!user?._id) throw new Error('target missing');\nawait Meteor.callAsync('removeRoomOwner', rid, user._id);","handlingStrategy":"validation","validationCode":"const target = Users.findOne({ _id: userId });\nif (!target?.username) {\n  // target missing: skip call and refresh pickers\n}","typeGuard":"const isRemovableUser = (u: { _id?: string; username?: string } | null | undefined): u is { _id: string; username: string } =>\n  Boolean(u?._id && u?.username);","tryCatchPattern":"try {\n  await Meteor.callAsync('removeRoomOwner', rid, userId);\n} catch (err) {\n  if (err instanceof Meteor.Error && err.error === 'error-invalid-user') {\n    // target vanished: refresh member data\n  }\n}","preventionTips":["Pass the target's _id, not username","Resolve users through a fresh lookup","Purge stale entries from selection UI"],"tags":["users","meteor-methods","validation"],"backgroundTag":"user-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}