different-ai/openwork · error

Failed to load ${connection.name}'s apps (${response.status}

Error message

Failed to load ${connection.name}'s apps (${response.status}).

What it means

useConnectionMcpAppCatalog fetches GET /v1/mcp-connections/:id/mcp-apps per connection and throws this error on a non-ok response. The interpolated connection name makes it clear which connection's catalog failed, and the status code hints at the cause.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/org-dashboards-data.tsx:385

  });
}

/** A flat catalog containing only connections that expose launchable MCP Apps. */
export function useConnectionMcpAppCatalog(connections: Array<{ id: string; name: string }>) {
  const { orgContext } = useOrgDashboard();
  const organizationId = orgContext?.organization.id ?? "";
  return useQueries({
    queries: connections.map((connection) => ({
      enabled: Boolean(organizationId),
      queryKey: orgDashboardsQueryKeys.connectionApps(organizationId, connection.id),
      queryFn: async (): Promise<ConnectionMcpApp[]> => {
        const { response, payload } = await requestJson(
          `/v1/mcp-connections/${encodeURIComponent(connection.id)}/mcp-apps`,
          { method: "GET" },
          20000,
        );
        if (!response.ok) {
          throw new Error(getErrorMessage(payload, `Failed to load ${connection.name}'s apps (${response.status}).`));
        }
        const apps = isRecord(payload) && Array.isArray(payload.apps) ? payload.apps : [];
        return apps.map(parseConnectionApp).filter((app): app is ConnectionMcpApp => app !== null);
      },
    })),
    combine: (results) => {
      const data = flattenConnectionMcpAppCatalog(connections, results.map((result) => result.data ?? []));
      const isLoading = mcpAppCatalogIsLoading(data.length, results.some((result) => result.isPending));
      return {
        data,
        isLoading,
        error: data.length === 0 && !isLoading
          ? results.find((result) => result.error)?.error ?? null
          : null,
      };
    },
  });
}

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Use the name/status in the message to identify the failing connection, then check its existence and your access on the connections screen
  2. For timeouts, verify the MCP server is reachable and responding quickly, then retry
  3. Re-sign-in if the status is 401
  4. If the connection no longer exists, remove or recreate it and reload the dashboard
Defensive patterns

Strategy: fallback

Validate before calling

// skip the catalog query for connections known to be unreachable
if (connection.status !== 'connected') return [];

Try / catch

const appsQuery = useConnectionMcpAppCatalog(connection);
const apps = appsQuery.data ?? [];
if (appsQuery.error) {
  showPerConnectionWarning(connection.name, appsQuery.error.message); // render rest of dashboard normally
}

Prevention

When it happens

Trigger: Non-2xx from the apps endpoint: 401 session expired, 403 no access to that MCP connection, 404 the connection was deleted while the dashboard was open, 408/timeout (20s budget) surfacing as an error status, 5xx server failure.

Common situations: An MCP connection removed by an admin while a dashboard referencing it is open; gateway timeout because the MCP server is slow to enumerate apps; expired Den session; connection pointing at an unreachable MCP server.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/42b60dcd479dc5d1. Report an issue: GitHub.