RocketChat/Rocket.Chat · error · Error

Trigger is not configured to use an external service

Error message

Trigger is not configured to use an external service

What it means

Thrown by the POST livechat/triggers/:_id/external-service/call route when the loaded Livechat trigger either has no actions or its actions are not all of type 'use-external-service'. The guard isExternalServiceTrigger requires every action in trigger.actions to have name === 'use-external-service'. This route exists only to invoke an external webhook, so a trigger configured for a different action type (e.g. send-message) is a caller/configuration mistake.

Source

Thrown at apps/meteor/ee/server/api/v1/omnichannel/triggers.ts:86

			numRequestsAllowed: 10,
			intervalTimeInMS: 60000,
		},
		validateParams: isLivechatTriggerWebhookCallParams,
		license: ['livechat-enterprise'],
	},
	{
		async post() {
			const { _id: triggerId } = this.urlParams;
			const { token: visitorToken, extraData } = this.bodyParams;

			const trigger = await LivechatTrigger.findOneById(triggerId);

			if (!trigger) {
				throw new Error('Invalid trigger');
			}

			if (!trigger?.actions.length || !isExternalServiceTrigger(trigger)) {
				throw new Error('Trigger is not configured to use an external service');
			}

			const { params: { serviceTimeout = 5000, serviceUrl, serviceFallbackMessage = 'trigger-default-fallback-message' } = {} } =
				trigger.actions[0];

			if (!serviceUrl) {
				throw new Error('Invalid service URL');
			}

			const token = settings.get<string>('Livechat_secret_token');

			if (!token) {
				throw new Error('Livechat secret token is not configured');
			}

			const body = {
				metadata: extraData,
				visitorToken,

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Open the trigger in Administration > Omnichannel > Triggers and confirm its action is set to 'Use an external service' (name === 'use-external-service') with a configured serviceUrl.
  2. If using the REST API to create/edit the trigger, ensure every entry in the actions array has name: 'use-external-service' and a params.serviceUrl.
  3. Verify you are passing the correct triggerId in the URL path; a different trigger with a non-external-service action will fail this check.
  4. Confirm isExternalServiceTrigger semantics: ALL actions must be external-service, not just the first one.

Example fix

// before - trigger saved with wrong action type
{
  "actions": [{ "name": "send-message", "params": { "msg": "hi" } }]
}

// after - configure as external service
{
  "actions": [{
    "name": "use-external-service",
    "params": {
      "sender": "queue",
      "name": "my-bot",
      "serviceUrl": "https://bot.example.com/inbox",
      "serviceTimeout": 5000,
      "serviceFallbackMessage": "Sorry, no agents available"
    }
  }]
}
Defensive patterns

Strategy: validation

Validate before calling

import { LivechatTrigger } from '@rocket.chat/models';
import { isExternalServiceTrigger } from '@rocket.chat/core-typings';

async function assertTriggerReady(triggerId: string) {
  const trigger = await LivechatTrigger.findOneById(triggerId);
  if (!trigger) throw new Error('Invalid trigger');
  if (!trigger.actions?.length || !isExternalServiceTrigger(trigger)) {
    throw new Error(`Trigger ${triggerId} is not an external-service trigger`);
  }
  if (!trigger.actions[0].params?.serviceUrl) {
    throw new Error(`Trigger ${triggerId} has no serviceUrl`);
  }
  return trigger;
}

// call before invoking /external-service/call
await assertTriggerReady(triggerId);

Type guard

import type { ILivechatTrigger, ILivechatUseExternalServiceAction } from '@rocket.chat/core-typings';

// already exported by @rocket.chat/core-typings:
export const isExternalServiceTrigger = (
  trigger: ILivechatTrigger,
): trigger is ILivechatTrigger & { actions: ILivechatUseExternalServiceAction[] } =>
  trigger.actions.every((a) => a.name === 'use-external-service');

const isExternalServiceUrlConfigured = (
  trigger: ILivechatTrigger,
): boolean =>
  isExternalServiceTrigger(trigger) &&
  !!trigger.actions[0]?.params?.serviceUrl;

Try / catch

try {
  const res = await fetch(`/api/v1/livechat/triggers/${triggerId}/external-service/call`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ token: visitorToken, extraData })
  });
  if (!res.ok) throw new Error(await res.text());
} catch (e) {
  if (e instanceof Error && e.message.includes('not configured to use an external service')) {
    // surface a configuration prompt to the admin instead of retrying
  }
}

Prevention

When it happens

Trigger: Calling POST /api/v1/livechat/triggers/<triggerId>/external-service/call with a visitorToken where the trigger referenced by <triggerId> was saved with actions of name 'send-message' (or with an empty actions array). The license livechat-enterprise is required by the route, so it only applies on EE.

Common situations: Admin saved a Livechat trigger with a 'Send a message' action, then the omnichannel widget or a custom integration tries to call the external-service endpoint against that same trigger ID. Also occurs after a trigger was edited to switch action types but the client still holds the old trigger ID, or a trigger was created via API with the wrong action schema.

Related errors


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