RocketChat/Rocket.Chat · error · Error
There must be a parent room to create a discussion.
Error message
There must be a parent room to create a discussion.
What it means
Thrown by the Apps Engine room bridge's createDiscussion when an app tries to create a discussion whose room has no parent room id (prid) or whose prid does not resolve to an existing room. Rocket.Chat discussions are threaded conversations that must be anchored to a parent channel/group, so the bridge verifies the parent exists in the database before delegating to createDiscussion.
Source
Thrown at apps/meteor/app/apps/server/bridges/rooms.ts:275
protected async createDiscussion(
room: IRoom,
parentMessage: IMessage | undefined = undefined,
reply: string | undefined = '',
members: Array<string> = [],
appId: string,
): Promise<string> {
this.orch.debugLog(`The App ${appId} is creating a new discussion.`, room);
const rcRoom = await this.orch.getConverters()?.get('rooms').convertAppRoom(room);
let rcMessage;
if (parentMessage) {
rcMessage = await this.orch.getConverters()?.get('messages').convertAppMessage(parentMessage);
}
if (!rcRoom.prid || !(await Rooms.findOneById(rcRoom.prid))) {
throw new Error('There must be a parent room to create a discussion.');
}
// #TODO: #AppsEngineTypes - Remove explicit types and typecasts once the apps-engine definition/implementation mismatch is fixed.
const discussion = {
prid: rcRoom.prid,
t_name: rcRoom.fname as string,
pmid: rcMessage ? rcMessage._id : undefined,
reply: reply && reply.trim() !== '' ? reply : undefined,
users: members.length > 0 ? members : [],
};
const { rid } = await createDiscussion(room.creator.id, discussion);
return rid;
}
protected getModerators(roomId: string, appId: string): Promise<IUser[]> {
this.orch.debugLog(`The App ${appId} is getting room moderators for room id: ${roomId}`);View on GitHub (pinned to f9d3ec372b)
Solutions
- Set room.prid to the _id of a real parent channel/group/private-team before calling createDiscussion.
- Look up the parent room first (e.g. read.getRoomById) and validate it exists and the app can access it before creating the discussion.
- Guard the call with a try/catch and surface a user-facing message instead of crashing the app flow when the parent is gone.
Example fix
// before
const room: IRoom = { ...sharedRoomFields };
await modify.getCreator().startDiscussion(room, msg).setDisplayName('Thread').create();
// after
const parent = await read.getRoomReader().getById(parentRoomId);
if (!parent) {
// bail out gracefully
return;
}
const room: IRoom = { ...sharedRoomFields, prid: parent.id } as any;
await modify.getCreator().startDiscussion(room, msg).setDisplayName('Thread').create(); Defensive patterns
Strategy: validation
Validate before calling
const parent = await read.getRoomReader().getById(room.prid);
if (!parent) {
throw new Error('Cannot create discussion: parent room does not exist');
} Type guard
function hasValidParent(room: IRoom): room is IRoom & { prid: string } {
return typeof room.prid === 'string' && room.prid.length > 0;
} Try / catch
try {
await modify.getCreator().startDiscussion(room, msg).create();
} catch (err) {
if (err instanceof Error && err.message.includes('parent room')) {
// parent missing or deleted — handle gracefully
} else {
throw err;
}
} Prevention
- Always populate room.prid from a freshly-read parent room id.
- Read the parent room immediately before creating the discussion to detect deletion.
- Treat prid absence as a hard precondition in your app logic.
When it happens
Trigger: An app calls createDiscussion with an IRoom whose prid is undefined/empty, or with a prid that points to a room that was deleted or never existed. The check is `!rcRoom.prid || !(await Rooms.findOneById(rcRoom.prid))`.
Common situations: App author forgets to set room.prid; copies a room object from a channel read but strips prid; parent room is deleted in the window between the app reading it and creating the discussion; prid is mistyped or taken from the wrong field.
Related errors
- User not subscribed to room
- roomId was not provided.
- Invalid Api parameter provided, it must be a valid IApi obje
- Invalid command parameter provided, must be a string.
- Invalid Slash Command parameter provided, it must be a valid
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/32feed11be550a91.
Report an issue: GitHub.