RocketChat/Rocket.Chat · warning · Error

Param "${params.members.key}" must be an array if provided

Error message

Param "${params.members.key}" must be an array if provided

What it means

Thrown during channel creation when params.members.value is present but not an array. The check is explicitly 'if provided' - a missing members param is fine; a present-but-wrong-type one is rejected. The param key name is interpolated into the message.

Source

Thrown at apps/meteor/server/api/v1/channels.ts:1022

	teams?: { key: string; value?: string[] };
	teamId?: { key: string; value?: string };
}) {
	const teamId = params.teamId?.value;

	const team = teamId && (await Team.getInfoById(teamId));
	if (
		(!teamId && !(await hasPermissionAsync(params.user.value, 'create-c'))) ||
		(teamId && team && !(await hasPermissionAsync(params.user.value, 'create-team-channel', team.roomId)))
	) {
		throw new Error('unauthorized');
	}

	if (!params.name?.value) {
		throw new Error(`Param "${params.name?.key}" is required`);
	}

	if (params.members?.value && !Array.isArray(params.members.value)) {
		throw new Error(`Param "${params.members.key}" must be an array if provided`);
	}

	if (params.customFields?.value && !(typeof params.customFields.value === 'object')) {
		throw new Error(`Param "${params.customFields.key}" must be an object if provided`);
	}

	if (params.teams?.value && !Array.isArray(params.teams.value)) {
		throw new Error(`Param ${params.teams.key} must be an array`);
	}
}

async function createChannel(
	userId: string,
	params: {
		name?: string;
		members?: string[];
		customFields?: Record<string, any>;
		extraData?: Record<string, any>;

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Send members as a JSON array: members: ['user1', 'user2'].
  2. If accepting CSV input is desired, split it server-side before this check.
  3. Validate the members shape client-side before submission.

Example fix

// before - request body
{ "name": "room", "members": "alice,bob" }

// after
{ "name": "room", "members": ["alice", "bob"] }
Defensive patterns

Strategy: validation

Validate before calling

function normalizeMembers(members) {
  if (members == null) return undefined;
  if (typeof members === 'string') return members.split(',').map(s => s.trim()).filter(Boolean);
  if (Array.isArray(members)) return members;
  throw new Error('members must be an array');
}

Type guard

function isStringArray(value) {
  return Array.isArray(value) && value.every(v => typeof v === 'string');
}

Try / catch

try {
  await api.createChannel({ name, members });
} catch (e) {
  if (/must be an array/.test(e.message)) {
    // coerce and retry once
    members = Array.isArray(members) ? members : [members];
    return api.createChannel({ name, members });
  }
  throw e;
}

Prevention

When it happens

Trigger: Submitting members as a comma-separated string, a single object, or any non-array value instead of a JSON array of usernames.

Common situations: Client serializing members with the wrong content-type or joining them into a string; API consumer passing members: 'user1,user2' instead of members: ['user1','user2'].

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/e58a1f299e1c2eeb. Report an issue: GitHub.