tinyhumansai/openhuman · error · Error
mcp.health.opErrorGeneric
Error message
mcp.health.opErrorGeneric
What it means
Bulk reconnect from the MCP health toolbar: handleReconnectAll runs Promise.allSettled over mcpClientsApi.connect(id) for every selected server, always refreshes statuses so the health dots reflect reality, and only then throws the localized 'mcp.health.opErrorGeneric' if ANY individual connect rejected. Partial success is expected - the throw tells the toolbar 'not all succeeded' but carries no per-server detail.
Solutions
- Read the per-server status dots after the refresh - they were updated before the throw and show which servers actually failed
- Open the failing server's detail / reconnect it individually to get its real error message
- Fix or remove the dead entries (bad config, unreachable host) so bulk actions can go green
- If a transient network blip is suspected, run Reconnect-all again once
Example fix
// before - single generic error for any partial failure
if (results.some(r => r.status === 'rejected')) {
throw new Error(t('mcp.health.opErrorGeneric'));
}
// after - keep the generic throw but include the failing ids for triage
const failed = results
.map((r, i) => (r.status === 'rejected' ? serverIds[i] : null))
.filter((id): id is string => id !== null);
if (failed.length > 0) {
throw new Error(`${t('mcp.health.opErrorGeneric')} (${failed.join(', ')})`);
} Defensive patterns
Strategy: fallback
Try / catch
// consume the bulk action knowing partial success is normal
try {
await handleReconnectAll(serverIds);
} catch {
// dots were refreshed before the throw - trust them, not this message
await fetchStatuses();
// reconnect failures individually to obtain their concrete errors
} Prevention
- After any bulk action, read the per-server status dots (refreshed before the throw) rather than the generic message
- Prune dead/unreachable servers from the selection before bulk reconnecting
- Treat 'some rejected' as a triage signal: drill into individual servers for real error text
When it happens
Trigger: Selecting multiple servers and clicking Reconnect-all where at least one connect(id) rejects - unreachable server, spawn failure, invalid transport config, or auth error on any member of the batch.
Common situations: Bulk-selecting a mixed set of healthy and dead servers; a dead server's rejection masking that the rest reconnected; treating the generic toolbar error as 'everything failed' when the dots show otherwise.
Related errors
- MCP events GET
- Socket not connected
- Timed out waiting for browser sign-in. Try again.
- --auth-token must not be empty
- ` ` was not found on OpenHuman's PATH. Install it (or its…
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/3820b0ef6b5448a4.
Report an issue: GitHub.
Appendix: 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 7491200858)