RocketChat/Rocket.Chat · error · RoomNotFoundError

room-not-found

room-not-found

Error message

Room not found

What it means

RoomNotFoundError (`room-not-found`) thrown by useOpenRoom's queryFn when the route lacks the room type or reference segment, i.e. the URL cannot identify any room. It is a client-side precondition failure raised before any network request is made.

Solutions

  1. Inspect the URL that triggered the navigation and make sure the type and name segments are present and URL-encoded.
  2. Fix the caller that builds the route (router.push/replace) so reference and type can never be undefined.
  3. Add a route guard that redirects malformed room URLs to home instead of mounting the room view.

Example fix

// before
directRoute.push({ rid }); // type/reference missing in some paths

// after
roomCoordinator.openRouteLink(type, { name: reference }, router.getSearchParameters());
Defensive patterns

Strategy: validation

Validate before calling

const hasRoomRouteParams = (type?: string, reference?: string): boolean => Boolean(type && reference);

Type guard

const isRoomNotFound = (error: unknown): error is RocketChatError<'room-not-found'> =>
	Boolean(error && typeof error === 'object' && 'error' in error && (error as { error: string }).error === 'room-not-found');

Try / catch

try {
	await openRoom(type, reference);
} catch (error) {
	if (isRoomNotFound(error) && (!type || !reference)) {
		redirect('/home'); // malformed URL, nothing to retry
		return;
	}
	throw error;
}

Prevention

When it happens

Trigger: Navigating to a room route whose params are empty — e.g. /channel/ (no name), a programmatic router.push({ type, reference }) with reference undefined, or a broken deep link that lost its path segment.

Common situations: A route template built with an undefined variable; trailing-slash or rewritten URLs stripping the name; unit tests mounting the room context without providing route params.

Related errors


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

Appendix: source

Thrown at apps/meteor/client/views/room/hooks/useOpenRoom.ts:74

		// we need to add uid and username here because `user` is not loaded all at once (see UserProvider -> Meteor.user())
		queryKey: roomsQueryKeys.roomReference(reference, type, user?._id, user?.username),

		// Render immediately from local cache when we already know the rid; queryFn still runs in
		// the background to revalidate permissions / fetch fresh room fields.
		placeholderData: tryCacheShortcut,

		queryFn: async (): Promise<{ rid: IRoom['_id'] }> => {
			const cached = tryCacheShortcut();
			if (cached) {
				LegacyRoomManager.open({ typeName: type + reference, rid: cached.rid });
				return cached;
			}
			if ((user && !user.username) || (!user && !allowAnonymousRead)) {
				throw new NotAuthorizedError();
			}

			if (!reference || !type) {
				throw new RoomNotFoundError(undefined, { type, reference });
			}

			let roomData: IRoom;
			try {
				roomData = await getRoomByTypeAndName(type, reference);
			} catch (error) {
				const errorCode = error && typeof error === 'object' && 'error' in error ? error.error : undefined;

				// "No permission" means the room exists but the user can't see it — surface the
				// not-found/no-access screen rather than retrying it as a transient failure.
				if (errorCode === 'error-no-permission') {
					throw new RoomNotFoundError(undefined, { type, reference });
				}

				if (errorCode !== 'error-invalid-room') {
					throw error;
				}

View on GitHub (pinned to 2f18297792)