RocketChat/Rocket.Chat · error · Meteor.Error

error-param-required

error-param-required

Error message

The required "roomId" query param is missing

What it means

Thrown by GET chat.syncMessages (apps/meteor/server/api/v1/chat.ts:715) when the roomId query param is falsy, with error-param-required. The endpoint's query schema requires roomId as a string with no minLength, so an empty roomId= passes validation and only dies here; a fully missing roomId is normally caught by schema validation first (this guard is the handler-level backstop and the documented error for older builds).

Solutions

  1. Always include a real room id: GET /api/v1/chat.syncMessages?roomId=GENERAL&lastUpdate=2024-01-01T00:00:00Z.
  2. Validate roomId is a non-empty string client-side before building the URL.
  3. Skip blank entries in room lists feeding the sync loop.
  4. Fetch the room id from rooms.info/rooms.list at startup rather than hardcoding.

Example fix

// before
const url = `/api/v1/chat.syncMessages?roomId=${rid}`; // rid === '' -> error

// after
if (!rid) throw new Error('roomId required');
const url = `/api/v1/chat.syncMessages?roomId=${encodeURIComponent(rid)}`;
Defensive patterns

Strategy: validation

Validate before calling

if (typeof roomId !== 'string' || roomId.trim() === '') throw new Error('roomId query param is required');
await rc.get('/api/v1/chat.syncMessages', { params: { roomId, lastUpdate } });

Type guard

const hasRoomId = (p: Record<string, unknown>): p is { roomId: string } =>
  typeof p.roomId === 'string' && p.roomId.length > 0;

Try / catch

try {
  await rc.get('/api/v1/chat.syncMessages', { params });
} catch (e) {
  if (e?.errorType === 'error-param-required') skipRoom(params.roomId); // blank entry, log and continue
  else throw e;
}

Prevention

When it happens

Trigger: GET /api/v1/chat.syncMessages?roomId= (empty value), or on servers without query validation a request with no roomId at all. Also when a URL builder drops the param (undefined stringified) or the roomId variable is empty before templating.

Common situations: Sync loops where roomId comes from a config/room list and one entry is blank; query-string encoders that omit empty values inconsistently; clients written before the endpoint enforced query schemas.

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/386267d8011e8749. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/server/api/v1/chat.ts:719

								},
							},
							required: ['updated', 'deleted'],
							additionalProperties: false,
						},
						success: { type: 'boolean', enum: [true] },
					},
					required: ['result', 'success'],
					additionalProperties: false,
				}),
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
			},
		},
		async function action() {
			const { roomId, lastUpdate, fromTs, count, next, previous, type } = this.queryParams;

			if (!roomId) {
				throw new Meteor.Error('error-param-required', 'The required "roomId" query param is missing');
			}

			if (!lastUpdate && !type) {
				throw new Meteor.Error('error-param-required', 'The "type" or "lastUpdate" parameters must be provided');
			}

			if (lastUpdate && isNaN(Date.parse(lastUpdate))) {
				throw new Meteor.Error('error-lastUpdate-param-invalid', 'The "lastUpdate" query parameter must be a valid date');
			}

			const getMessagesQuery = {
				...(lastUpdate && { lastUpdate: new Date(lastUpdate) }),
				...(fromTs && { fromTs: new Date(fromTs) }),
				...(next && { next }),
				...(previous && { previous }),
				...(count && { count }),
				...(type && { type }),
			};

View on GitHub (pinned to e4b8178b20)