{"record":{"id":"6bc672c6795671f4","repo":"RocketChat/Rocket.Chat","slug":"invalid-user","errorCode":null,"errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/rooms.ts","lineNumber":100,"sourceCode":"\t\tdelete extraData.t;\n\t\tdelete extraData.ro;\n\t\tdelete extraData.customFields;\n\n\t\treturn extraData;\n\t}\n\n\tprivate async createChannel(userId: string, room: ICoreRoom, members: string[]): Promise<string> {\n\t\treturn (await createChannelMethod(userId, room.name || '', members, room.ro, room.customFields, this.prepareExtraData(room))).rid;\n\t}\n\n\tprivate async createDirectMessage(userId: string, members: string[]): Promise<string> {\n\t\treturn (await createDirectMessage(members, userId)).rid;\n\t}\n\n\tprivate async createPrivateGroup(userId: string, room: ICoreRoom, members: string[]): Promise<string> {\n\t\tconst user = await Users.findOneById(userId);\n\t\tif (!user) {\n\t\t\tthrow new Error('Invalid user');\n\t\t}\n\t\treturn (await createPrivateGroupMethod(user, room.name || '', members, room.ro, room.customFields, this.prepareExtraData(room))).rid;\n\t}\n\n\tprotected async getById(roomId: string, appId: string): Promise<IRoom> {\n\t\tthis.orch.debugLog(`The App ${appId} is getting the roomById: \"${roomId}\"`);\n\n\t\t// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.\n\t\tconst promise: Promise<IRoom | undefined> = this.orch.getConverters()?.get('rooms').convertById(roomId);\n\t\treturn promise as Promise<IRoom>;\n\t}\n\n\tprotected async getByName(roomName: string, appId: string): Promise<IRoom> {\n\t\tthis.orch.debugLog(`The App ${appId} is getting the roomByName: \"${roomName}\"`);\n\n\t\t// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.\n\t\tconst promise: Promise<IRoom | undefined> = this.orch.getConverters()?.get('rooms').convertByName(roomName);\n\t\treturn promise as Promise<IRoom>;","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/bridges/rooms.ts#L82-L118","documentation":"When creating a private group, AppRoomBridge.createPrivateGroup resolves the creator with Users.findOneById(userId) and throws 'Invalid user' when no user document matches room.creator.id — unlike the channel/DM paths, the private-group creation method needs the full user object, so the creator must exist.","triggerScenarios":"room.creator.id references a deleted user; an app passes its own bot user id while the bot user is missing; creator id copied from stale cached data, a different workspace, or a federation/import mismatch.","commonSituations":"Users deleted between when the app captured the id and when it creates the group; dev databases reset while the app kept persisted creator ids; typos in hand-built creator objects.","solutions":["Verify the creator exists first (e.g. read.getUserById) before attempting to create the private group","Prefer the current user from the execution context over persisted ids","Re-fetch a fresh room/user reference instead of reusing long-lived cached objects","Surface a clear app-level error instead of letting the bridge throw"],"exampleFix":"// before\nconst room = { type: RoomType.PRIVATE_GROUP, creator: { id: staleUserId }, name: 'ops' };\nawait app.getRocketChat().getChat().createRoom(room, members); // staleUserId deleted -> throws\n// after\nconst creator = await this.read.getUserById(staleUserId);\nif (!creator) throw new Error('creator no longer exists');\nconst room = { type: RoomType.PRIVATE_GROUP, creator, name: 'ops' };\nawait app.getRocketChat().getChat().createRoom(room, members);","handlingStrategy":"validation","validationCode":"const creator = await this.read.getUserById(room.creator.id);\nif (!creator) {\n  throw new Error(`cannot create private group: creator ${room.creator.id} not found`);\n}\nawait app.getRocketChat().getChat().createRoom({ ...room, creator }, members);","typeGuard":null,"tryCatchPattern":"try {\n  await app.getRocketChat().getChat().createRoom(room, members);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Invalid user') {\n    app.getLogger().warn('private group creator no longer exists');\n    return;\n  }\n  throw err;\n}","preventionTips":["Resolve creators through the user reader right before creating private groups","Prefer the contextual user (e.g. from the action/event context) over persisted ids","Re-validate persisted user ids on app upgrade or workspace migration","Remember only the private-group path checks the creator — channels/DMs fail later with different errors"],"tags":["apps-engine","rooms","private-group","user-not-found","validation"],"backgroundTag":"user-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}