{"record":{"id":"1ac09851ee864ee8","repo":"RocketChat/Rocket.Chat","slug":"error-registering-provider","errorCode":null,"errorMessage":"error-registering-provider","messagePattern":"error-registering-provider","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/outboundCommunication.ts","lineNumber":22,"sourceCode":"\tIOutboundEmailMessageProvider,\n\tIOutboundMessageProviders,\n\tIOutboundPhoneMessageProvider,\n} from '@rocket.chat/apps-engine/definition/outboundCommunication';\n\nimport { getOutboundService } from '../../../../server/lib/omnichannel/outboundcommunication';\n\nexport class OutboundCommunicationBridge extends OutboundMessageBridge {\n\tconstructor(private readonly orch: IAppServerOrchestrator) {\n\t\tsuper();\n\t}\n\n\tprotected async registerPhoneProvider(provider: IOutboundPhoneMessageProvider, appId: string): Promise<void> {\n\t\ttry {\n\t\t\tthis.orch.debugLog(`App ${appId} is registering a phone outbound provider.`);\n\t\t\tgetOutboundService().outboundMessageProvider.registerPhoneProvider(provider);\n\t\t} catch (err) {\n\t\t\tthis.orch.getRocketChatLogger().error({ appId, err, msg: 'Failed to register phone provider' });\n\t\t\tthrow new Error('error-registering-provider');\n\t\t}\n\t}\n\n\tprotected async registerEmailProvider(provider: IOutboundEmailMessageProvider, appId: string): Promise<void> {\n\t\ttry {\n\t\t\tthis.orch.debugLog(`App ${appId} is registering an email outbound provider.`);\n\t\t\tgetOutboundService().outboundMessageProvider.registerEmailProvider(provider);\n\t\t} catch (err) {\n\t\t\tthis.orch.getRocketChatLogger().error({ appId, err, msg: 'Failed to register email provider' });\n\t\t\tthrow new Error('error-registering-provider');\n\t\t}\n\t}\n\n\tprotected async unRegisterProvider(provider: IOutboundMessageProviders, appId: string): Promise<void> {\n\t\ttry {\n\t\t\tthis.orch.debugLog(`App ${appId} is unregistering an outbound provider.`);\n\t\t\tgetOutboundService().outboundMessageProvider.unregisterProvider(appId, provider.type);\n\t\t} catch (err) {","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/bridges/outboundCommunication.ts#L4-L40","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the Rocket.Chat server log for 'Failed to register phone provider' — the logged err holds the actual cause","Unregister providers on disable/uninstall (the bridge exposes unRegisterProvider) so re-enabling cannot double-register","Guard registration with an isRegistered check or your own in-app flag","Make sure the provider object implements the full IOutboundPhoneMessageProvider interface (including type)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const registeredProviders = new Set<string>();\nconst registerPhoneProviderOnce = async (provider: IOutboundPhoneMessageProvider) => {\n  if (registeredProviders.has(provider.type)) return; // avoid duplicate registration\n  await app.getRocketChat().getOutboundCommunication().registerPhoneProvider(provider);\n  registeredProviders.add(provider.type);\n};","typeGuard":"const isPhoneProvider = (p: unknown): p is IOutboundPhoneMessageProvider =>\n  typeof p === 'object' && p !== null && typeof (p as any).type === 'string' &&\n  typeof (p as any).sendMessage === 'function';","tryCatchPattern":"try {\n  await app.getRocketChat().getOutboundCommunication().registerPhoneProvider(provider);\n} catch (err) {\n  if (err instanceof Error && err.message === 'error-registering-provider') {\n    // real cause is in server logs under 'Failed to register phone provider'\n    app.getLogger().error('phone provider registration failed', err);\n    return;\n  }\n  throw err;\n}","preventionTips":["Register providers in exactly one lifecycle hook (onActivate), not in both install and activate","Track in-app which provider types are registered; skip duplicates","Unregister on disable so re-enabling starts from a clean slate","Check server logs for the wrapped err — the thrown message is generic"],"tags":["apps-engine","outbound-communication","phone-provider","registration","wrapped-error"],"backgroundTag":"provider-registration-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}