tinyhumansai/openhuman · warning

mcp.connectAuth.oauthTimeout

Error message

mcp.connectAuth.oauthTimeout

What it means

MCP OAuth connect flow: after opening the provider's authorize URL in the system browser, the modal polls mcpClientsApi.status() every 2.5s for up to 180s waiting for that server to report 'connected' (the OAuth callback completing core-side). Past 3 minutes it gives up with this localized timeout message.

Source

Thrown at app/src/components/channels/mcp/ConnectAuthModal.tsx:297

    setBusy(true);
    setError(null);
    setOauthWaiting(true);
    void (async () => {
      try {
        const url = await mcpClientsApi.oauthBegin(server.server_id);
        await openUrl(url);
        const started = Date.now();
        const poll = async (): Promise<void> => {
          const statuses = await mcpClientsApi.status();
          const mine = statuses.find(s => s.server_id === server.server_id);
          if (mine?.status === 'connected') {
            const result = await mcpClientsApi.connect(server.server_id);
            onConnected(result.tools ?? []);
            onClose();
            return;
          }
          if (Date.now() - started > 180000) {
            throw new Error(t('mcp.connectAuth.oauthTimeout'));
          }
          window.setTimeout(() => {
            void poll().catch(handlePollError);
          }, 2500);
        };
        const handlePollError = (err: unknown) => {
          setError(err instanceof Error ? err.message : String(err));
          setOauthWaiting(false);
          setBusy(false);
        };
        await poll().catch(handlePollError);
      } catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        log('oauth failed: %s', msg);
        setError(msg);
        setOauthWaiting(false);
        setBusy(false);
      }

View on GitHub (pinned to a221052e0d)

Solutions

  1. Retry the connect flow and complete consent promptly in the opened browser tab
  2. Confirm the authorize URL actually opened (openUrl) and that the MCP server's redirect URI is correctly registered
  3. After a timeout, check the server's status in the MCP list — if it shows connected, call connect again instead of re-authenticating
Defensive patterns

Strategy: retry

Validate before calling

// Before declaring timeout, do one final authoritative status check:
const statuses = await mcpClientsApi.status();
const mine = statuses.find(s => s.server_id === id);
const connected = mine?.status === 'connected';
if (!connected) { /* only now show the timeout error */ }

Type guard

const isConnected = (s: { status?: string } | undefined): boolean =>
  s?.status === 'connected';

Try / catch

try {
  await pollUntilConnected(serverId, 180_000);
} catch (e) {
  if (e instanceof Error && e.message === t('mcp.connectAuth.oauthTimeout')) {
    // keep modal open, offer Retry — re-auth is often all that is needed
    setOauthWaiting(false);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: User never completes consent in the browser; the OAuth callback never reaches the core (redirect URI misconfigured, wrong browser account); server needs longer than 180s to become connected; polling error path ends the wait early.

Common situations: Browser blocked or user abandoned the consent tab; MCP server's OAuth client not registered for the loopback redirect; slow provider authorization backends.

Understand the failure class

Related errors


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