RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-urls

error-invalid-urls

Error message

Invalid URLs

What it means

First of the two 'error-invalid-urls' failures in _verifyRequiredFields: Match.test(integration.urls, [String]) fails when urls is missing, not an array, or an array containing non-string entries. The REST layer does not coerce this field, so the exact shape — an array of strings — must arrive intact.

Source

Thrown at apps/meteor/server/lib/integrations/lib/validateOutgoingIntegration.ts:40

		throw new Meteor.Error('error-invalid-event-type', 'Invalid event type', {
			function: 'validateOutgoing._verifyRequiredFields',
		});
	}

	if (!integration.username || !Match.test(integration.username, String) || integration.username.trim() === '') {
		throw new Meteor.Error('error-invalid-username', 'Invalid username', {
			function: 'validateOutgoing._verifyRequiredFields',
		});
	}

	if (outgoingEvents[integration.event].use.targetRoom && !integration.targetRoom) {
		throw new Meteor.Error('error-invalid-targetRoom', 'Invalid Target Room', {
			function: 'validateOutgoing._verifyRequiredFields',
		});
	}

	if (!Match.test(integration.urls, [String])) {
		throw new Meteor.Error('error-invalid-urls', 'Invalid URLs', {
			function: 'validateOutgoing._verifyRequiredFields',
		});
	}

	integration.urls = integration.urls.filter((url) => url && url.trim() !== '');

	if (integration.urls.length === 0) {
		throw new Meteor.Error('error-invalid-urls', 'Invalid URLs', {
			function: 'validateOutgoing._verifyRequiredFields',
		});
	}
}

async function _verifyUserHasPermissionForChannels(userId: IUser['_id'], channels: string[]): Promise<void> {
	for (let channel of channels) {
		if (scopedChannels.includes(channel)) {
			if (channel === 'all_public_channels') {
				// No special permissions needed to add integration to public channels

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Send urls as an array of strings: urls: ['https://a.example/hook']
  2. Split comma-separated input before submitting: urls: csv.split(',').map((u) => u.trim())
  3. Check the outgoing integrations REST examples in the docs, which show the array form

Example fix

// before
{ urls: 'https://a.example/hook,https://b.example/hook' }

// after
{ urls: ['https://a.example/hook', 'https://b.example/hook'] }
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(urls) || !urls.every((u) => typeof u === 'string')) {
  throw new TypeError('urls must be an array of strings');
}

Prevention

When it happens

Trigger: POST /api/v1/integrations.create with urls as a single string ('https://a.example/hook'), a comma-separated string, an array of objects, or omitted entirely for an outgoing integration.

Common situations: Writers assuming the API accepts a CSV like the channel field does; form code that sends one URL as a bare string when only one endpoint is configured; JSON payloads built by hand where the array brackets are lost.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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