{"record":{"id":"1ac09851ee864ee8","repo":"RocketChat/Rocket.Chat","slug":"error-registering-provider","errorCode":null,"errorMessage":"error-registering-provider","messagePattern":"error-registering-provider","errorType":"exception","errorClass":"Error","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/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/outboundCommunication.ts#L4-L40","documentation":"Generic wrapper thrown by OutboundCommunicationBridge.registerPhoneProvider when the underlying getOutboundService().outboundMessageProvider.registerPhoneProvider call throws for any reason. The original error is logged via the Rocket.Chat logger with appId and msg 'Failed to register phone provider', but the rethrown error discards the original so callers only see 'error-registering-provider'. It is a catch-all signal that phone provider registration failed, not a specific cause.","triggerScenarios":"An App's enable/onInit hook registers a phone outbound provider whose object does not conform to IOutboundPhoneMessageProvider, the outbound service is uninitialized (Omnichannel/outbound plugin not loaded), or the same provider type was already registered and the registry rejected a duplicate.","commonSituations":"Omnichannel/Omnichannel outbound feature disabled or license missing on the workspace; duplicate registration across App reinstalls without cleanup; provider implementation throwing in its constructor or type field; version skew between the App's apps-engine API and the server's outbound service contract.","solutions":["Inspect the server logs for the original `err` logged just before this throw — it contains the real cause (line: this.orch.getRocketChatLogger().error({ appId, err, msg: 'Failed to register phone provider' })).","Verify Omnichannel and the outbound communication service are enabled on the workspace.","Ensure your provider implements IOutboundPhoneMessageProvider fully (type field unique, required methods present).","Register providers in onPostInstall / onEnable only once and unregister them in onDisable to avoid duplicate-key failures."],"exampleFix":"// before\ntry {\n  await outbound.registerPhoneProvider(myProvider, appId);\n} catch (e) {\n  // 'error-registering-provider' — no detail\n}\n\n// after\n// First: check server logs for the original err.\n// Then ensure provider has a unique type and Omnichannel is enabled.\nconst provider = { type: 'my-sms', ...methods };\nif (!outbound.isRegistered(provider.type)) {\n  await outbound.registerPhoneProvider(provider, appId);\n}","handlingStrategy":"try-catch","validationCode":"// validate provider shape before registering\nfunction isValidPhoneProvider(p: any): boolean {\n  return p && typeof p.type === 'string' && p.type.length > 0 && typeof p.send === 'function';\n}\nif (!isValidPhoneProvider(provider)) {\n  throw new Error('Phone provider missing required fields (type, send)');\n}\nawait outbound.registerPhoneProvider(provider, appId);","typeGuard":"function isPhoneProvider(p: unknown): p is IOutboundPhoneMessageProvider {\n  return typeof p === 'object' && p !== null && typeof (p as any).type === 'string' && typeof (p as any).send === 'function';\n}","tryCatchPattern":"try {\n  await outbound.registerPhoneProvider(provider, appId);\n} catch (e) {\n  // the real cause is in the server log under msg 'Failed to register phone provider'\n  this.app.getLogger().error({ msg: 'Phone provider registration failed', providerType: provider.type, err: e });\n  throw e;\n}","preventionTips":["Check server logs for the original err — the bridge swallows the cause.","Register providers in onPostInstall/onEnable and unregister in onDisable to keep state symmetric.","Confirm Omnichannel and the outbound communication service are enabled before registering.","Use a globally unique provider type to avoid duplicate-registration failures."],"tags":["apps-engine","outbound-bridge","omnichannel","provider-registration","wrapped-error"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}