RocketChat/Rocket.Chat · error · Error

Discussion not found

Error message

Discussion not found

What it means

getDiscussionByID() throws 'Discussion not found' when Rooms.state.find fails to locate a room with _id === drid that also has a truthy prid (parent room id) — the two conditions that define a discussion record in the local store. It is the strict variant of findDiscussionByID and has no server fallback.

Solutions

  1. Use findDiscussionByID and treat undefined as 'not available yet'.
  2. Ensure the discussion room has been synced (open it or await subscription load) before the strict call.
  3. Validate that the id you pass is the drid from the message's d field, not the parent channel id.

Example fix

// before
const discussion = await chat.getDiscussionByID(drid);

// after
const discussion = await chat.findDiscussionByID(drid);
if (!discussion) return; // not synced yet, or drid is not a discussion
Defensive patterns

Strategy: validation

Validate before calling

const discussion = await chat.findDiscussionByID(drid);
if (!discussion) return; // not synced yet, or drid is not a discussion

Type guard

const isDiscussionRoom = (room: IRoom | undefined): room is IRoom & { prid: string } =>
  Boolean(room?.prid);

Prevention

When it happens

Trigger: Calling getDiscussionByID with a drid that points to a regular (non-discussion) room, a discussion room not yet synced into the Rooms store (just created, subscription pending), or an invalid id.

Common situations: Clicking a 'discussion created' system message immediately after creation before the new room syncs; passing a channel rid where a discussion drid was expected; cache cleared mid-session.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@2f18297792 (2026-08-18). Data as JSON: /api/errors/7566e3bb15d3e7e0. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/client/lib/chats/data.ts:287

		}

		return room;
	};

	const isSubscribedToRoom = async (): Promise<boolean> => !!Subscriptions.state.find((record) => record.rid === rid);

	const joinRoom = async (): Promise<void> => {
		await sdk.rest.post('/v1/rooms.join', { roomId: rid });
	};

	const findDiscussionByID = async (drid: IRoom['_id']): Promise<IRoom | undefined> =>
		Rooms.state.find((record) => Boolean(record._id === drid && record.prid));

	const getDiscussionByID = async (drid: IRoom['_id']): Promise<IRoom> => {
		const discussion = await findDiscussionByID(drid);

		if (!discussion) {
			throw new Error('Discussion not found');
		}

		return discussion;
	};

	const createStrictGetter = <TFind extends (...args: any[]) => Promise<any>>(
		find: TFind,
		errorMessage: string,
	): ((...args: Parameters<TFind>) => Promise<Exclude<Awaited<ReturnType<TFind>>, undefined>>) => {
		return async (...args) => {
			const result = await find(...args);

			if (!result) {
				throw new Error(errorMessage);
			}

			return result;
		};

View on GitHub (pinned to 2f18297792)