RocketChat/Rocket.Chat · error · Error

App not found

Error message

App not found

What it means

Thrown by AppClientOrchestrator.updateApp after POST /apps/:id returns a body without an `app` key. The message 'App not found' is misleading — the guard is a structural check on the response, not a 404 lookup. The real cause is that the server did not return the expected { app: App } envelope after an update.

Source

Thrown at apps/meteor/client/apps/orchestrator.ts:130

			marketplace: true,
			version,
			permissionsGranted,
		})) as { app: App };
		return app;
	}

	public async updateApp(appId: string, version: string, permissionsGranted?: IPermission[]): Promise<App> {
		const result = await sdk.rest.post<'/apps/:id'>(`/apps/${appId}`, {
			appId,
			marketplace: true,
			version,
			permissionsGranted,
		});

		if ('app' in result) {
			return result.app;
		}
		throw new Error('App not found');
	}

	public async buildExternalUrl(appId: string, purchaseType: 'buy' | 'subscription' = 'buy', details = false): Promise<IAppExternalURL> {
		const result = await sdk.rest.get('/apps/buildExternalUrl', {
			appId,
			purchaseType,
			details: `${details}`,
		});

		if ('url' in result) {
			return result;
		}

		throw new Error('Failed to build external url');
	}

	public async buildExternalAppRequest(appId: string) {
		const result = await sdk.rest.get('/apps/buildExternalAppRequest', {

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Inspect the raw POST /apps/:id response in DevTools to see what shape the server actually returned.
  2. Verify the appId still exists (call getApp/getInstalledApps first) and the target version is valid.
  3. Confirm the caller has 'manage-apps' permission and the apps engine is enabled.
  4. Treat the message as a response-shape error, not literally 'not found', when debugging.
Defensive patterns

Strategy: type-guard

Type guard

function hasAppKey(r: unknown): r is { app: App } {
  return typeof r === 'object' && r !== null && 'app' in r;
}

Try / catch

try {
  const app = await orchestrator.updateApp(appId, version, perms);
} catch (e) {
  if ((e as Error).message === 'App not found') {
    // misleading: response shape invalid; check network + permissions
  }
}

Prevention

When it happens

Trigger: Updating an app whose id does not exist (server returns an error-shaped 200), the app failed to update due to missing permissions/version, or the server returned a different envelope such as { success: true } without nesting the app. The structural 'app' in result check fails and this generic message is thrown.

Common situations: Calling updateApp for an appId that was uninstalled elsewhere; the user lacks 'manage-apps'; the requested version is not installed/available; server version returns a different update response shape; apps-engine not enabled so the route returns a non-app body.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/7f65030f3cc2a7c0. Report an issue: GitHub.