RocketChat/Rocket.Chat · error · Error
Invalid response from API
Error message
Invalid response from API
What it means
Thrown by AppClientOrchestrator.getInstalledApps after a GET /apps/installed?includeClusterStatus=true whose response body does not contain an `apps` key. The method uses a runtime structural check ('apps' in result) because the SDK typing cannot guarantee the shape; a missing key means the server returned something unexpected (an error object, an empty 200, or a different schema version).
Source
Thrown at apps/meteor/client/apps/orchestrator.ts:56
}
public handleError(error: unknown): void {
if (hasAtLeastOnePermission(['manage-apps'])) {
dispatchToastMessage({
type: 'error',
message: error,
});
}
}
public async getInstalledApps(): Promise<App[]> {
const result = await sdk.rest.get<'/apps/installed'>('/apps/installed', { includeClusterStatus: 'true' });
if ('apps' in result) {
// TODO: chapter day: multiple results are returned, but we only need one
return result.apps as App[];
}
throw new Error('Invalid response from API');
}
public async getAppsFromMarketplace(isAdminUser?: boolean): Promise<{ apps: App[]; error?: unknown }> {
let result: App[] = [];
try {
result = await sdk.rest.get('/apps/marketplace', { isAdminUser: isAdminUser ? isAdminUser.toString() : 'false' });
} catch (e) {
if (isErrorObject(e)) {
return { apps: [], error: e.error };
}
if (typeof e === 'string') {
return { apps: [], error: e };
}
}
if (!Array.isArray(result)) {
// TODO: chapter day: multiple results are returned, but we only need one
return { apps: [], error: 'Invalid response from API' };View on GitHub (pinned to f9d3ec372b)
Solutions
- Open DevTools Network and inspect the raw /apps/installed response body — a missing `apps` key is the defect to fix.
- Confirm the Apps subsystem is enabled on the server (Administration > Apps) and that the user has 'manage-apps' permission.
- Verify server and client versions are compatible; a much older server may not return the expected envelope.
- If a proxy is in front, ensure it does not rewrite 200 responses for the /apps/ path.
- Report the actual returned shape to harden the structural check or update the rest-typings contract.
Defensive patterns
Strategy: type-guard
Type guard
function hasAppsKey(r: unknown): r is { apps: App[] } {
return typeof r === 'object' && r !== null && 'apps' in r;
} Try / catch
try {
const apps = await orchestrator.getInstalledApps();
} catch (e) {
if ((e as Error).message === 'Invalid response from API') {
// inspect network response; likely apps-engine disabled or version mismatch
}
} Prevention
- Verify the apps engine is enabled and the user has 'manage-apps' permission.
- Keep client and server versions compatible.
- Ensure proxies do not rewrite 200 responses on the /apps/ path.
When it happens
Trigger: The marketplace/apps engine is disabled on the server so /apps/installed returns a non-standard body; the server returned an error envelope (e.g. { error: '...' }) that still resolved with HTTP 200; an older/newer server version where the response key differs; the request was intercepted by a proxy that replaced the body.
Common situations: Apps-engine not enabled in deployment; version mismatch between client bundle and server (e.g. client newer than server); a gateway/auth layer returning a JSON error page with 200 status; the apps-engine microservice migration producing a transitional response shape.
Related errors
- App not found
- Failed to build external url
- Failed to build App Request external url
- Failed to get categories
- Invalid server info
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/3524e64db00d4f7d.
Report an issue: GitHub.