RocketChat/Rocket.Chat · error · Error

apps-engine-not-loaded

Error message

apps-engine-not-loaded

What it means

Thrown by getProviderManager(), the gateway for every provider-manager operation (URL generation, join callbacks, provider events): Apps.self?.isLoaded() is false, so the Apps-Engine subsystem is not (yet) loaded. The engine loads asynchronously during server startup and can also be absent if apps subsystem initialization failed, so any video-conf provider call racing the boot sequence hits this.

Source

Thrown at apps/meteor/server/services/video-conference/service.ts:902

			callId,
		};
	}

	private async joinCall(
		call: ExternalVideoConference,
		user: AtLeast<IUser, '_id' | 'username' | 'name' | 'avatarETag'> | undefined,
		options: VideoConferenceJoinOptions,
	): Promise<string> {
		void callbacks.runAsync('onJoinVideoConference', call._id, user?._id);

		await this.runOnUserJoinEvent(call._id, user as IVideoConferenceUser);

		return this.getUrl(call, user, options);
	}

	private async getProviderManager(): Promise<AppVideoConfProviderManager> {
		if (!Apps.self?.isLoaded()) {
			throw new Error('apps-engine-not-loaded');
		}

		const manager = Apps.self?.getManager()?.getVideoConfProviderManager();
		if (!manager) {
			throw new Error(availabilityErrors.NO_APP);
		}

		return manager;
	}

	private async getRoomName(rid: string): Promise<string> {
		const room = await Rooms.findOneById<Pick<IRoom, '_id' | 'name' | 'fname'>>(rid, { projection: { name: 1, fname: 1 } });

		return room?.fname || room?.name || rid;
	}

	private async generateNewUrl(call: ExternalVideoConference): Promise<string> {
		if (!videoConfProviders.isProviderAvailable(call.providerName)) {

View on GitHub (pinned to e4b8178b20)

Solutions

  1. Wait for the server to fully finish startup (apps loaded; admin UI shows apps ready) before issuing video conference requests
  2. Check Administration > Apps and server logs to confirm the Apps-Engine initialized without errors
  3. Restart the server if the engine failed to load
  4. For automation, add a readiness probe that retries until video conf provider operations succeed

Example fix

// before
await videoConfService.startCall(uid, rid); // during boot -> Error('apps-engine-not-loaded')

// after
if (!Apps.self?.isLoaded()) {
	await waitForAppsEngineLoaded(); // poll isLoaded() with backoff
}
await videoConfService.startCall(uid, rid);
Defensive patterns

Strategy: retry

Validate before calling

import { Apps } from '.../apps/server';

if (!Apps.self?.isLoaded()) {
	await new Promise((resolve) => setTimeout(resolve, 1000)); // or subscribe to an apps-loaded event
}
const url = await videoConfService.joinCall(call, user, options);

Try / catch

for (let attempt = 0; attempt < 5; attempt++) {
	try { return await videoConfService.joinCall(call, user, options); }
	catch (err) {
		if (!(err instanceof Error && err.message === 'apps-engine-not-loaded')) throw err;
		await backoff(attempt); // engine still booting
	}
}

Prevention

When it happens

Trigger: Issuing video conference start/join/provider-manager requests while the server is still bootstrapping (engine still loading apps); after a restart where the Apps-Engine failed to initialize; automated health-check or integration scripts that fire the moment the HTTP port opens.

Common situations: CI/e2e suites and bots that start calling APIs as soon as the port accepts connections; startup-order dependencies in custom services that assume video conf is ready; a crashed apps-engine leaving isLoaded() false.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-08-18). Data as JSON: /api/errors/abd02461a21956c0. Report an issue: GitHub.