RocketChat/Rocket.Chat · error · Meteor.Error

error-room-param-not-provided

error-room-param-not-provided

Error message

The parameter "roomId" or "roomName" is required

What it means

Thrown by getRoomFromParams, the shared resolver behind findPrivateGroupByIdOrName and most groups.* mutation endpoints (groups.addAll, groups.addModerator, groups.kick, ...), when the request identifies no target room: neither a roomId nor a roomName key is present, or both keys are present and both are empty strings. One non-empty value of either kind is required. Quirk: sending only roomId as an empty string does NOT raise this error - it falls through to a lookup of '' and surfaces error-room-not-found instead.

Solutions

  1. Include exactly one non-empty roomId or roomName (top-level) in the request body for POST endpoints / query for GET endpoints
  2. If you only have the room name, send roomName; if you have the id from rooms/info or a subscription, send roomId
  3. Guard on the client: build params only when one of the two is truthy, and fail fast with your own message otherwise

Example fix

// before
await sdk.post('groups.addAll', { activeUsersOnly: true });

// after
await sdk.post('groups.addAll', { roomId, activeUsersOnly: true });
Defensive patterns

Strategy: validation

Validate before calling

function roomTarget(params) {
  const target = params.roomId?.trim() ? { roomId: params.roomId.trim() }
    : params.roomName?.trim() ? { roomName: params.roomName.trim() }
    : null;
  if (!target) throw new Error('provide a non-empty roomId or roomName');
  return target;
}
// sdk.post('groups.addAll', { ...roomTarget(cfg), activeUsersOnly: true })

Type guard

type RoomTarget = { roomId: string } | { roomName: string };
const isRoomTarget = (p: Partial<{ roomId?: unknown; roomName?: unknown }>): p is RoomTarget =>
  (typeof p.roomId === 'string' && p.roomId.length > 0) || (typeof p.roomName === 'string' && p.roomName.length > 0);

Try / catch

try { await sdk.post(route, body); } catch (e) {
  if (e.error === 'error-room-param-not-provided') failFast('missing room selector');
}

Prevention

When it happens

Trigger: POST groups.addAll with body { activeUsersOnly: true } (room target forgotten); body containing { roomId: '', roomName: '' }; clients that build params from optional variables that are undefined on both branches, so the keys are stripped by JSON.stringify.

Common situations: Copy-pasting a groups.* call template and forgetting the room selector; branching code that sets roomId in one branch and roomName in another but neither in a third; passing the room inside a nested object or wrong key spelling (rid, groupId, name) instead of roomId/roomName.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/api/v1/groups.ts:74

import { leaveRoomMethod } from '../../meteor-methods/rooms/leaveRoom';
import { removeRoomLeader } from '../../meteor-methods/rooms/removeRoomLeader';
import { removeRoomModerator } from '../../meteor-methods/rooms/removeRoomModerator';
import { removeRoomOwner } from '../../meteor-methods/rooms/removeRoomOwner';
import { removeUserFromRoomMethod } from '../../meteor-methods/rooms/removeUserFromRoom';
import { saveRoomSettings } from '../../meteor-methods/rooms/saveRoomSettings';
import { executeUnarchiveRoom } from '../../meteor-methods/rooms/unarchiveRoom';
import { API } from '../api';
import { addUserToFileObj } from '../lib/addUserToFileObj';
import { composeRoomWithLastMessage } from '../lib/composeRoomWithLastMessage';
import { getPaginationItems } from '../lib/getPaginationItems';
import { getUserFromParams, getUserListFromParams, getUsernameListFromParams } from '../lib/getUserFromParams';

async function getRoomFromParams(params: { roomId?: string } | { roomName?: string }): Promise<IRoom> {
	if (
		(!('roomId' in params) && !('roomName' in params)) ||
		('roomId' in params && !(params as { roomId?: string }).roomId && 'roomName' in params && !(params as { roomName?: string }).roomName)
	) {
		throw new Meteor.Error('error-room-param-not-provided', 'The parameter "roomId" or "roomName" is required');
	}

	const roomOptions = {
		projection: {
			...roomAccessAttributes,
			t: 1,
			ro: 1,
			name: 1,
			fname: 1,
			prid: 1,
			archived: 1,
			broadcast: 1,
		},
	};

	const room = await (() => {
		if ('roomId' in params) {
			return Rooms.findOneById(params.roomId || '', roomOptions);

View on GitHub (pinned to e4b8178b20)