RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-channel-start-with-chars

error-invalid-channel-start-with-chars

Error message

Invalid channel. Start with @ or #

What it means

Thrown by updateIncomingIntegration's validateChannels when a comma-separated channel entry does not start with '#' or '@'. The string is split on ',', trimmed, and each segment's first character is checked against ['@', '#']. Empty segments from trailing or double commas also trigger it because channel[0] is undefined.

Source

Thrown at apps/meteor/server/meteor-methods/integrations/incoming/updateIncomingIntegration.ts:36

		updateIncomingIntegration(
			integrationId: string,
			integration: INewIncomingIntegration | IUpdateIncomingIntegration,
		): IIntegration | null;
	}
}

function validateChannels(channelString: string | undefined): string[] {
	if (!channelString || typeof channelString.valueOf() !== 'string' || channelString.trim() === '') {
		throw new Meteor.Error('error-invalid-channel', 'Invalid channel', {
			method: 'updateIncomingIntegration',
		});
	}

	const channels = channelString.split(',').map((channel) => channel.trim());

	for (const channel of channels) {
		if (!validChannelChars.includes(channel[0])) {
			throw new Meteor.Error('error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', {
				method: 'updateIncomingIntegration',
			});
		}
	}

	return channels;
}

export const updateIncomingIntegration = async (
	userId: string,
	integrationId: string,
	integration: INewIncomingIntegration | IUpdateIncomingIntegration,
): Promise<IIntegration | null> => {
	const channels = validateChannels(integration.channel);

	let currentIntegration;

	if (await hasPermissionAsync(userId, 'manage-incoming-integrations')) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Prefix rooms with # and users with @ in every segment: '#general,#dev,@rocket.cat'
  2. Normalize before submitting: split, trim, filter(Boolean), re-add prefixes, join
  3. Validate in the form layer so the update call never carries malformed segments

Example fix

// before
await Meteor.callAsync('updateIncomingIntegration', id, { ...payload, channel: 'general, dev' });
// after
const channel = payload.channel.split(',').map((c) => c.trim()).filter(Boolean).map((c) => (/^[#@]/.test(c) ? c : `#${c}`)).join(',');
await Meteor.callAsync('updateIncomingIntegration', id, { ...payload, channel });
Defensive patterns

Strategy: validation

Validate before calling

const segments = integration.channel.split(',').map((s) => s.trim()).filter(Boolean);
if (segments.some((s) => !['@', '#'].includes(s[0]))) throw new Error('each channel entry must start with # or @');
await Meteor.callAsync('updateIncomingIntegration', integrationId, { ...integration, channel: segments.join(',') });

Type guard

const isValidChannelList = (c: unknown): c is string =>
  typeof c === 'string' && c.trim() !== '' &&
  c.split(',').every((s) => ['@', '#'].includes(s.trim()[0]));

Try / catch

try {
  await Meteor.callAsync('updateIncomingIntegration', integrationId, integration);
} catch (err) {
  if (err instanceof Meteor.Error && err.error === 'error-invalid-channel-start-with-chars') { /* normalize segments and resubmit */ }
}

Prevention

When it happens

Trigger: channel: 'general' on update; 'general,#dev'; trailing comma '#general,'; double comma '#general,,#ops'.

Common situations: Edit forms that join a channel multi-select with ',' but include an empty option; hand-edited channel lists; porting from the old outgoing-integration payload style without prefixes.

Related errors


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