{"record":{"id":"67111497beb83880","repo":"RocketChat/Rocket.Chat","slug":"apps-engine-not-loaded","errorCode":"apps-engine-not-loaded","errorMessage":"apps-engine-not-loaded","messagePattern":"apps-engine-not-loaded","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/ee/server/api/v1/omnichannel/lib/outbound.ts","lineNumber":48,"sourceCode":"\t\tif (type !== undefined && !this.isProviderValid(type)) {\n\t\t\tthrow new Error('Invalid type');\n\t\t}\n\n\t\treturn this.provider.getOutboundMessageProviders(type);\n\t}\n\n\tpublic getProviderMetadata(providerId: string): Promise<IOutboundProviderMetadata> {\n\t\tconst provider = this.provider.findOneByProviderId(providerId);\n\t\tif (!provider) {\n\t\t\tthrow new Error('error-invalid-provider');\n\t\t}\n\n\t\treturn this.getProviderManager().getProviderMetadata(provider.appId, provider.type);\n\t}\n\n\tprivate getProviderManager() {\n\t\tif (!Apps.self?.isLoaded()) {\n\t\t\tthrow new Error('apps-engine-not-loaded');\n\t\t}\n\n\t\tconst manager = Apps.self?.getManager()?.getOutboundCommunicationProviderManager();\n\t\tif (!manager) {\n\t\t\tthrow new Error('apps-engine-not-configured-correctly');\n\t\t}\n\n\t\treturn manager;\n\t}\n\n\tpublic sendMessage(providerId: string, message: IOutboundMessage) {\n\t\tconst provider = this.provider.findOneByProviderId(providerId);\n\t\tif (!provider) {\n\t\t\tthrow new Error('error-invalid-provider');\n\t\t}\n\n\t\treturn this.getProviderManager().sendOutboundMessage(provider.appId, provider.type, message);\n\t}","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/api/v1/omnichannel/lib/outbound.ts#L30-L66","documentation":"getProviderManager requires the Apps Engine to be loaded (Apps.self.isLoaded()); calling outbound metadata/send before the apps subsystem finishes loading throws 'apps-engine-not-loaded'. The state is transient — it clears once apps finish loading at startup.","triggerScenarios":"Omnichannel outbound endpoints hit during the server startup window before AppsEngine reports loaded; or with the apps subsystem disabled/failing to load.","commonSituations":"Health-check or warmup scripts calling the API immediately after boot; slow app installs delaying readiness; a request racing the apps-loaded event.","solutions":["Retry with backoff until Apps.self.isLoaded() is true (a few seconds at most)","Sequence startup-dependent work after the apps-loaded signal instead of at boot","If it never loads, inspect apps-engine logs for load failures (broken app, missing dependency)"],"exampleFix":"// before\nawait outboundMessageProvider.getProviderMetadata(providerId); // during startup → apps-engine-not-loaded\n\n// after\nwhile (!Apps.self?.isLoaded()) {\n  await sleep(500);\n}\nawait outboundMessageProvider.getProviderMetadata(providerId);","handlingStrategy":"retry","validationCode":"import { Apps } from '@rocket.chat/apps';\n\nif (!Apps.self?.isLoaded()) {\n  // transient startup state: wait for the apps engine before touching outbound APIs\n  await new Promise((resolve) => Apps.self?.once && Apps.self.once('loaded', resolve));\n}\nawait outboundMessageProvider.getProviderMetadata(providerId);","typeGuard":null,"tryCatchPattern":"for (let attempt = 0; attempt < 10; attempt++) {\n  try {\n    return await outboundMessageProvider.getProviderMetadata(providerId);\n  } catch (error) {\n    if (error instanceof Error && error.message === 'apps-engine-not-loaded' && attempt < 9) {\n      await sleep(1000 * (attempt + 1)); // startup race: engine loads within seconds\n      continue;\n    }\n    throw error;\n  }\n}","preventionTips":["Delay warmup/health scripts until the apps engine signals loaded","Treat this as transient — but bound the retries and alert if it persists","If it never clears, check apps-engine load failures in logs"],"tags":["omnichannel","outbound","apps-engine","startup"],"backgroundTag":"service-not-initialized","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"}