RocketChat/Rocket.Chat · error · Meteor.Error

error-type-param-required

error-type-param-required

Error message

The "type" parameter is required when using the "next" or "previous" parameters

What it means

messages/get requires the type parameter whenever next or previous (cursor pagination) is used, because the cursor indexes a different collection per type — live messages for UPDATED, the trash collection for DELETED. Omitting it throws Meteor.Error 'error-type-param-required'.

Source

Thrown at apps/meteor/server/publications/messages.ts:249

			cursor?: {
				next: string | null;
				previous: string | null;
			};
	  }
	| false
	| IMessage[]
	| { messages: IMessage[]; firstUnread?: any; unreadNotLoaded?: number }
> => {
	if (!(await canAccessRoomIdAsync(rid, fromId))) {
		throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'messages/get' });
	}

	if (type && !['UPDATED', 'DELETED'].includes(type)) {
		throw new Meteor.Error('error-type-param-not-supported', 'The "type" parameter must be either "UPDATED" or "DELETED"');
	}

	if ((next || previous) && !type) {
		throw new Meteor.Error('error-type-param-required', 'The "type" parameter is required when using the "next" or "previous" parameters');
	}

	if (next && previous) {
		throw new Meteor.Error('error-cursor-conflict', 'You cannot provide both "next" and "previous" parameters');
	}

	if ((next || previous) && lastUpdate) {
		throw new Meteor.Error(
			'error-cursor-and-lastUpdate-conflict',
			'The attributes "next", "previous" and "lastUpdate" cannot be used together',
		);
	}

	// `fromTs` only bounds the query on the `lastUpdate` path; neither cursor pagination nor the channel
	// history fallback honors it, so accepting it there would silently widen the result set.
	if (fromTs && !lastUpdate) {
		throw new Meteor.Error('error-fromTs-requires-lastUpdate', 'The "fromTs" parameter can only be used together with "lastUpdate"');
	}

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Always send type: 'UPDATED' or 'DELETED' together with next/previous
  2. Persist the type alongside the cursor in your paging state so both travel together
  3. When adding cursor pagination, update both the request builder and the state store

Example fix

// before
Meteor.call('messages/get', rid, { next: cursor.next }); // throws error-type-param-required

// after
Meteor.call('messages/get', rid, { type: 'UPDATED', next: cursor.next });
Defensive patterns

Strategy: validation

Validate before calling

const hasTypeForCursor = (params: { next?: string; previous?: string; type?: string }): boolean =>
  !(params.next || params.previous) || Boolean(params.type);

Type guard

type CursorParams = { type: 'UPDATED' | 'DELETED'; next?: string } | { type: 'UPDATED' | 'DELETED'; previous?: string };

const isCursorParams = (p: unknown): p is CursorParams => {
  const v = p as CursorParams;
  return (v.type === 'UPDATED' || v.type === 'DELETED') && !(v.next && v.previous);
};

Prevention

When it happens

Trigger: Calling messages/get with next or previous set but no type parameter.

Common situations: Clients that copy the cursor fields out of a response but forget to carry the type they paged with; adding cursor paging incrementally to an existing integration.

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@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/e7c8c332b5b90f9b. Report an issue: GitHub.