tinyhumansai/openhuman · warning

mcp.health.opErrorGeneric

Error message

mcp.health.opErrorGeneric

What it means

Bulk reconnect: every selected id goes to mcpClientsApi.connect(id) through allSettled so one failure does not abort the batch; statuses are refreshed first so the health dots reflect reality, then if any promise rejected this generic error is thrown so the toolbar surfaces the partial/total failure — per-server detail lives in the refreshed statuses, not the exception.

Source

Thrown at app/src/components/channels/mcp/McpServersTab.tsx:448

    void fetchCatalog(
      debouncedCatalogFilters.query,
      debouncedCatalogFilters.transport,
      catalogPage + 1,
      true
    );
  };

  // Bulk lifecycle actions for the health toolbar. One failure doesn't abort the
  // batch (allSettled), and we always refresh status so the dots reflect reality
  // — but if any call rejected we then throw so the toolbar can surface the
  // failure (otherwise a partial/total failure would look like success).
  const handleReconnectAll = useCallback(
    async (serverIds: string[]) => {
      log('reconnect all: %o', serverIds);
      const results = await Promise.allSettled(serverIds.map(id => mcpClientsApi.connect(id)));
      await fetchStatuses();
      if (results.some(r => r.status === 'rejected')) {
        throw new Error(t('mcp.health.opErrorGeneric'));
      }
    },
    [fetchStatuses, t]
  );

  const handleDisconnectAll = useCallback(
    async (serverIds: string[]) => {
      log('disconnect all: %o', serverIds);
      const results = await Promise.allSettled(serverIds.map(id => mcpClientsApi.disconnect(id)));
      await fetchStatuses();
      if (results.some(r => r.status === 'rejected')) {
        throw new Error(t('mcp.health.opErrorGeneric'));
      }
    },
    [fetchStatuses, t]
  );

  const selectedServer =

View on GitHub (pinned to a221052e0d)

Solutions

  1. After the error, inspect the refreshed health dots / per-server status to identify which servers failed
  2. Open the failing server's detail and reconnect it individually to see the real error
  3. Fix each root cause (auth or endpoint) per server, then re-run the bulk action
Defensive patterns

Strategy: try-catch

Validate before calling

// Optional pre-filter: skip servers that cannot reconnect (e.g. unauthorized ones)
const statuses = await mcpClientsApi.status();
const candidates = serverIds.filter(id => {
  const s = statuses.find(x => x.server_id === id);
  return s?.status !== 'unauthorized';
});

Type guard

const hasRejected = (rs: PromiseSettledResult<unknown>[]): boolean =>
  rs.some(r => r.status === 'rejected');

Try / catch

try {
  await reconnectAll(ids);
} catch (e) {
  // partial failure by design: consult refreshed per-server statuses, not e
  await fetchStatuses();
  surfacePartialFailure();
}

Prevention

When it happens

Trigger: One or more connect(id) rejections inside a multi-select 'reconnect all' action: unreachable endpoint, expired auth, or an unknown server_id.

Common situations: Several installed servers where at least one has stale credentials or an offline endpoint.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/3820b0ef6b5448a4. Report an issue: GitHub.