{"record":{"id":"32feed11be550a91","repo":"RocketChat/Rocket.Chat","slug":"there-must-be-a-parent-room-to-create-a-discussion","errorCode":null,"errorMessage":"There must be a parent room to create a discussion.","messagePattern":"There must be a parent room to create a discussion\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/rooms.ts","lineNumber":275,"sourceCode":"\n\tprotected async createDiscussion(\n\t\troom: IRoom,\n\t\tparentMessage: IMessage | undefined = undefined,\n\t\treply: string | undefined = '',\n\t\tmembers: Array<string> = [],\n\t\tappId: string,\n\t): Promise<string> {\n\t\tthis.orch.debugLog(`The App ${appId} is creating a new discussion.`, room);\n\n\t\tconst rcRoom = await this.orch.getConverters()?.get('rooms').convertAppRoom(room);\n\n\t\tlet rcMessage;\n\t\tif (parentMessage) {\n\t\t\trcMessage = await this.orch.getConverters()?.get('messages').convertAppMessage(parentMessage);\n\t\t}\n\n\t\tif (!rcRoom.prid || !(await Rooms.findOneById(rcRoom.prid))) {\n\t\t\tthrow new Error('There must be a parent room to create a discussion.');\n\t\t}\n\n\t\t// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.\n\t\tconst discussion = {\n\t\t\tprid: rcRoom.prid,\n\t\t\tt_name: rcRoom.fname as string,\n\t\t\tpmid: rcMessage ? rcMessage._id : undefined,\n\t\t\treply: reply && reply.trim() !== '' ? reply : undefined,\n\t\t\tusers: members.length > 0 ? members : [],\n\t\t};\n\n\t\tconst { rid } = await createDiscussion(room.creator.id, discussion);\n\n\t\treturn rid;\n\t}\n\n\tprotected getModerators(roomId: string, appId: string): Promise<IUser[]> {\n\t\tthis.orch.debugLog(`The App ${appId} is getting room moderators for room id: ${roomId}`);","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/bridges/rooms.ts#L257-L293","documentation":"Thrown by the Rocket.Chat apps-engine rooms bridge when an app calls createDiscussion and the converted room object has no prid (parent room id), or the prid does not match any room in the database. Discussions in Rocket.Chat always live inside an existing parent channel, so both conditions are hard requirements. The check runs before the server-side createDiscussion is invoked.","triggerScenarios":"App invokes the rooms bridge createDiscussion with a room whose prid is undefined/empty, or whose prid points to a deleted or never-existing room (stale room id, or prid accidentally set to the new discussion's own id).","commonSituations":"Apps building the discussion room object by hand instead of deriving it from the parent; parent channel deleted between the read and the create; field-name mistakes (parentId or rid instead of prid).","solutions":["Set room.prid to the _id of an existing parent room, fetched fresh via the room reader right before creating the discussion.","Re-verify the parent room exists if the discussion flow is long-lived (wizard-style UI) and re-fetch its id when stale.","If the parent was deleted, pick another parent room or report to the user instead of retrying with the same prid."],"exampleFix":"// before\nconst room: IRoom = { ...newRoom, fname: 'Weekly sync' }; // no prid\nawait createDiscussion(room, parentMessage, reply, members, appId);\n\n// after\nconst parent = await this.read.getRoomReader().getById(context.getRoom().id);\nif (!parent) {\n  throw new Error('Parent room is gone; cannot create discussion');\n}\nconst room: IRoom = { ...newRoom, prid: parent.id, fname: 'Weekly sync' };\nawait createDiscussion(room, parentMessage, reply, members, appId);","handlingStrategy":"validation","validationCode":"const parent = room.prid ? await this.read.getRoomReader().getById(room.prid) : null;\nif (!parent) {\n  // abort: discussion requires an existing parent room\n  throw new Error('Parent room does not exist');\n}","typeGuard":"const hasParentRoomId = (room: IRoom): room is IRoom & { prid: string } =>\n  typeof room.prid === 'string' && room.prid.length > 0;","tryCatchPattern":"Catch per call and surface a user-facing message ('discussions need an existing parent channel'); do not retry with the same prid.","preventionTips":["Always derive prid from a room object just fetched via the room reader.","Never build the discussion room from scratch without prid.","Handle the case where the parent channel is deleted before the discussion is created."],"tags":["apps-engine","discussion","room","validation"],"backgroundTag":"parent-room-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"}