RocketChat/Rocket.Chat · error

error-registering-provider

Error message

error-registering-provider

What it means

AppOutboundCommunicationBridge.registerPhoneProvider wraps the registry call in try/catch: any failure from getOutboundService().outboundMessageProvider.registerPhoneProvider(provider) is logged with the original error (msg 'Failed to register phone provider', with appId and err) and re-thrown as this generic Error. The real cause is only visible in the server log, not in the exception.

Solutions

  1. Check the Rocket.Chat server log for 'Failed to register phone provider' — the logged err holds the actual cause
  2. Unregister providers on disable/uninstall (the bridge exposes unRegisterProvider) so re-enabling cannot double-register
  3. Guard registration with an isRegistered check or your own in-app flag
  4. Make sure the provider object implements the full IOutboundPhoneMessageProvider interface (including type)
Defensive patterns

Strategy: try-catch

Validate before calling

const registeredProviders = new Set<string>();
const registerPhoneProviderOnce = async (provider: IOutboundPhoneMessageProvider) => {
  if (registeredProviders.has(provider.type)) return; // avoid duplicate registration
  await app.getRocketChat().getOutboundCommunication().registerPhoneProvider(provider);
  registeredProviders.add(provider.type);
};

Type guard

const isPhoneProvider = (p: unknown): p is IOutboundPhoneMessageProvider =>
  typeof p === 'object' && p !== null && typeof (p as any).type === 'string' &&
  typeof (p as any).sendMessage === 'function';

Try / catch

try {
  await app.getRocketChat().getOutboundCommunication().registerPhoneProvider(provider);
} catch (err) {
  if (err instanceof Error && err.message === 'error-registering-provider') {
    // real cause is in server logs under 'Failed to register phone provider'
    app.getLogger().error('phone provider registration failed', err);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Registering a phone provider whose type is already registered for the appId (double registration after re-enable); passing a provider object that does not satisfy IOutboundPhoneMessageProvider (missing methods/type); the outbound communication service not being initialized when the bridge runs.

Common situations: Apps registering providers in both onInstall and onActivate; app disable paths that failed to unregister, leaving stale state; apps-engine version changes to the provider interface; server startup-order issues.

Related errors


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

Appendix: source

Thrown at apps/meteor/app/apps/server/bridges/outboundCommunication.ts:22

	IOutboundEmailMessageProvider,
	IOutboundMessageProviders,
	IOutboundPhoneMessageProvider,
} from '@rocket.chat/apps-engine/definition/outboundCommunication';

import { getOutboundService } from '../../../../server/lib/omnichannel/outboundcommunication';

export class OutboundCommunicationBridge extends OutboundMessageBridge {
	constructor(private readonly orch: IAppServerOrchestrator) {
		super();
	}

	protected async registerPhoneProvider(provider: IOutboundPhoneMessageProvider, appId: string): Promise<void> {
		try {
			this.orch.debugLog(`App ${appId} is registering a phone outbound provider.`);
			getOutboundService().outboundMessageProvider.registerPhoneProvider(provider);
		} catch (err) {
			this.orch.getRocketChatLogger().error({ appId, err, msg: 'Failed to register phone provider' });
			throw new Error('error-registering-provider');
		}
	}

	protected async registerEmailProvider(provider: IOutboundEmailMessageProvider, appId: string): Promise<void> {
		try {
			this.orch.debugLog(`App ${appId} is registering an email outbound provider.`);
			getOutboundService().outboundMessageProvider.registerEmailProvider(provider);
		} catch (err) {
			this.orch.getRocketChatLogger().error({ appId, err, msg: 'Failed to register email provider' });
			throw new Error('error-registering-provider');
		}
	}

	protected async unRegisterProvider(provider: IOutboundMessageProviders, appId: string): Promise<void> {
		try {
			this.orch.debugLog(`App ${appId} is unregistering an outbound provider.`);
			getOutboundService().outboundMessageProvider.unregisterProvider(appId, provider.type);
		} catch (err) {

View on GitHub (pinned to b2c16d5842)