RocketChat/Rocket.Chat · error · Error
apps-engine-not-loaded
Error message
apps-engine-not-loaded
What it means
Thrown by OutboundMessageProviderService.getProviderManager when Apps.self is not loaded (Apps.self?.isLoaded() returns falsy). The Apps Engine must finish loading before any outbound provider manager operation can run. Plain Error, code 'apps-engine-not-loaded'.
Source
Thrown at apps/meteor/ee/server/api/v1/omnichannel/lib/outbound.ts:48
if (type !== undefined && !this.isProviderValid(type)) {
throw new Error('Invalid type');
}
return this.provider.getOutboundMessageProviders(type);
}
public getProviderMetadata(providerId: string): Promise<IOutboundProviderMetadata> {
const provider = this.provider.findOneByProviderId(providerId);
if (!provider) {
throw new Error('error-invalid-provider');
}
return this.getProviderManager().getProviderMetadata(provider.appId, provider.type);
}
private getProviderManager() {
if (!Apps.self?.isLoaded()) {
throw new Error('apps-engine-not-loaded');
}
const manager = Apps.self?.getManager()?.getOutboundCommunicationProviderManager();
if (!manager) {
throw new Error('apps-engine-not-configured-correctly');
}
return manager;
}
public sendMessage(providerId: string, message: IOutboundMessage) {
const provider = this.provider.findOneByProviderId(providerId);
if (!provider) {
throw new Error('error-invalid-provider');
}
return this.getProviderManager().sendOutboundMessage(provider.appId, provider.type, message);
}View on GitHub (pinned to f9d3ec372b)
Solutions
- Defer the outbound call until the Apps Engine reports loaded (listen for the apps-engine loaded event / Apps.self.isLoaded()).
- Check Apps.self?.isLoaded() before calling and queue/retry if false.
- Inspect server logs for Apps Engine load failures and resolve those first.
- Avoid invoking outbound operations from boot-time migrations.
Example fix
// before: call during boot
app.onServerStart(() => svc.getProviderMetadata(id));
// after: wait for the engine
if (!Apps.self?.isLoaded()) {
await waitForAppsEngineLoaded();
}
svc.getProviderMetadata(id); Defensive patterns
Strategy: retry
Validate before calling
// Probe Apps Engine load state before calling
import { Apps } from '@rocket.chat/apps';
function appsEngineReady(): boolean {
return !!Apps.self?.isLoaded();
}
if (!appsEngineReady()) {
// queue the call until loaded, or warn
throw new Error('Apps Engine not loaded yet');
} Type guard
function appsEngineLoaded(apps: typeof Apps): boolean {
return !!apps.self?.isLoaded();
} Try / catch
async function withAppsEngineReady<T>(fn: () => T | Promise<T>): Promise<T> {
try {
return await fn();
} catch (e) {
if (e.message === 'apps-engine-not-loaded') {
await waitForAppsEngineLoaded();
return fn();
}
throw e;
}
} Prevention
- Do not call outbound operations from boot-time hooks; wait for the apps-engine loaded event.
- Expose an apps-engine readiness signal to omnichannel init code.
When it happens
Trigger: Calling getProviderMetadata/sendMessage during server startup before the Apps Engine has finished initializing, or after the engine failed to load. Also reachable via code paths invoked very early in boot.
Common situations: Startup race: an omnichannel init hook or a deferred job fires before Apps Engine load completes; Apps Engine disabled or crashed during boot; calling from a migration that runs pre-engine.
Related errors
- apps-engine-not-configured-correctly
- The user for app ${appId} is not registered.
- error-unregistering-provider
- Invalid type
- error-invalid-provider
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/67111497beb83880.
Report an issue: GitHub.