{"record":{"id":"3c4dae45c0832f6c","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-3c4dae","errorCode":"error-invalid-user","errorMessage":"Invalid user provided for erasing team","messagePattern":"Invalid user provided for erasing team","errorType":"error_code","errorClass":"MeteorError","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/lib/eraseTeam.ts","lineNumber":23,"sourceCode":"\nimport { eraseRoom } from '../../lib/eraseRoom';\nimport { SystemLogger } from '../../lib/logger/system';\nimport { deleteRoom } from '../../lib/rooms/deleteRoom';\n\ntype EraseRoomFnType = <T extends AtLeast<IUser, '_id' | 'name' | 'username' | 'roles'>>(rid: string, user: T) => Promise<boolean | void>;\n\nexport const eraseTeamShared = async <T extends AtLeast<IUser, '_id' | 'name' | 'username' | 'roles'>>(\n\tuser: T,\n\tteam: ITeam,\n\troomsToRemove: IRoom['_id'][] = [],\n\teraseRoomFn: EraseRoomFnType,\n) => {\n\tconst rooms: string[] = roomsToRemove.length\n\t\t? (await Team.getMatchingTeamRooms(team._id, roomsToRemove)).filter((roomId) => roomId !== team.roomId)\n\t\t: [];\n\n\tif (!user) {\n\t\tthrow new MeteorError('Invalid user provided for erasing team', 'error-invalid-user', {\n\t\t\tmethod: 'eraseTeamShared',\n\t\t});\n\t}\n\n\t// If we got a list of rooms to delete along with the team, remove them first\n\tawait Promise.all(rooms.map((room) => eraseRoomFn(room, user)));\n\n\t// Move every other room back to the workspace\n\tawait Team.unsetTeamIdOfRooms(user, team);\n\n\t// Remove the team's main room\n\tawait eraseRoomFn(team.roomId, user);\n\n\t// Delete all team memberships\n\tawait Team.removeAllMembersFromTeam(team._id);\n\n\t// And finally delete the team itself\n\tawait Team.deleteById(team._id);","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/lib/eraseTeam.ts#L5-L41","documentation":"eraseTeamShared (backing team deletion flows) requires the acting user object; a falsy user argument triggers MeteorError('Invalid user provided for erasing team', 'error-invalid-user') from @rocket.chat/core-services, where the first argument is the message and the second the machine-readable code. The guard runs before any destructive operation (rooms are only erased after it).","triggerScenarios":"Server code calling eraseTeamShared with null/undefined as the user — e.g. a Users.findOneById result used without a null check, or the requesting user being deleted between request validation and execution.","commonSituations":"Races where the acting user is deleted mid-operation, test/migration code passing partial objects, refactors that made the user parameter optional at the call site.","solutions":["Load and null-check the acting user before calling eraseTeamShared.","If the original actor may be gone, pass a valid admin/bot user as the actor for the audit trail.","Return early with a clear 'user not found' error instead of letting the shared helper throw."],"exampleFix":"// before\nconst user = await Users.findOneById(uid);\nawait eraseTeamShared(user, team, roomsToRemove, eraseRoom);\n\n// after\nconst user = await Users.findOneById(uid);\nif (!user) throw new Meteor.Error('error-invalid-user', 'Requesting user not found');\nawait eraseTeamShared(user, team, roomsToRemove, eraseRoom);","handlingStrategy":"type-guard","validationCode":"const user = await Users.findOneById(uid);\nif (!user) {\n\t// do not call eraseTeamShared; surface 'acting user not found'\n}","typeGuard":"function isFullUser<T extends Partial<IUser>>(u: T | null | undefined): u is T & { _id: string; username: string; roles: string[] } {\n\treturn !!u && typeof u._id === 'string' && typeof u.username === 'string' && Array.isArray(u.roles);\n}","tryCatchPattern":"try {\n\tawait eraseTeamShared(user, team, roomsToRemove, eraseRoom);\n} catch (e: any) {\n\tif (e?.error === 'error-invalid-user') {\n\t\t// acting user missing: reload/fall back to an admin actor and retry\n\t}\n\tthrow e;\n}","preventionTips":["Never pass an unchecked Users.findOneById result into destructive team flows","Fall back to a designated admin/bot actor when the original requester may have been deleted","In tests/migrations, construct the full AtLeast<IUser, '_id'|'name'|'username'|'roles'> shape explicitly"],"tags":["teams","user","validation","invalid-argument"],"backgroundTag":"invalid-argument","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}