RocketChat/Rocket.Chat · error · Error
apps-engine-not-initialized
apps-engine-not-initialized
Error message
apps-engine-not-initialized
What it means
_canEnableApp refuses to enable any app while the Apps Engine has not finished initializing: Apps.isInitialized() resolves false. It is the first guard in the enable flow, so it fires regardless of license state whenever the engine is still booting or was never started.
Solutions
- Wait for engine readiness before enabling: await Apps.isInitialized() (or wait for the apps-engine startup log) and then retry
- In tests, initialize the Apps Engine (app manager setup) before calling enable methods
- Move enable calls out of early startup hooks into a post-startup callback or queue that drains once the engine is ready
Example fix
// before
await Apps.enableApp(appId); // may throw apps-engine-not-initialized during boot
// after
while (!(await Apps.isInitialized())) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
await Apps.enableApp(appId); Defensive patterns
Strategy: validation
Validate before calling
if (!(await Apps.isInitialized())) {
// queue the enable for after engine startup instead of calling now
return queueEnableAfterEngineReady(appId);
}
await Apps.enableApp(appId); Try / catch
try {
await Apps.enableApp(appId);
} catch (err) {
if (err instanceof Error && err.message === 'apps-engine-not-initialized') {
// engine still booting: retry on a later tick / after startup event
} else {
throw err;
}
} Prevention
- Never call app enable/disable inside early Meteor.startup blocks; wait for engine-ready
- In tests, bootstrap the Apps Engine before exercising enable paths
- Log Apps.isInitialized() state during startup to catch slow initializations early
When it happens
Trigger: Calling an app-enable path (Apps API methods such as enableApp, or REST routes that enable apps) during server startup before the Apps Engine finished loading, or in tests where the engine was never bootstrapped.
Common situations: Server code enabling apps inside Meteor.startup before engine readiness; integration tests that skip engine setup; slow marketplace/app loading creating a startup race window.
Related errors
- apps-engine-not-loaded
- App could not be enabled
- apps-engine-not-loaded
- failed-to-create-direct-call
- failed-to-create-group-call
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/0498c3d5ed2e43c4.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/ee/server/lib/license/canEnableApp.ts:15
import type { IAppStorageItem } from '@rocket.chat/apps/dist/server/storage/IAppStorageItem';
import { Apps } from '@rocket.chat/core-services';
import type { LicenseModule } from '@rocket.chat/core-typings';
import { License, type LicenseImp } from '@rocket.chat/license';
import { getInstallationSourceFromAppStorageItem } from '../../../../lib/apps/getInstallationSourceFromAppStorageItem';
type _canEnableAppDependencies = {
Apps: typeof Apps;
License: LicenseImp;
};
export const _canEnableApp = async ({ Apps, License }: _canEnableAppDependencies, app: IAppStorageItem): Promise<void> => {
if (!(await Apps.isInitialized())) {
throw new Error('apps-engine-not-initialized');
}
// Migrated apps were installed before the validation was implemented
// so they're always allowed to be enabled
if (app.migrated) {
return;
}
if (app.info.addon && !License.hasModule(app.info.addon as LicenseModule)) {
throw new Error('app-addon-not-valid');
}
const source = getInstallationSourceFromAppStorageItem(app);
switch (source) {
case 'private':
if (await License.shouldPreventAction('privateApps')) {
throw new Error('license-prevented');
}View on GitHub (pinned to b2c16d5842)