{"record":{"id":"cfbb379cebfdd574","repo":"NousResearch/hermes-agent","slug":"oauth-authorization-failed","errorCode":null,"errorMessage":"OAuth authorization failed","messagePattern":"OAuth authorization failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/lib/mcp-dashboard-oauth.ts","lineNumber":59,"sourceCode":"    authWindow.close();\n    throw error;\n  }\n\n  let pollFailures = 0;\n  for (;;) {\n    let current: McpOAuthFlow;\n    try {\n      current = await status(started.flow_id);\n      pollFailures = 0;\n    } catch (error) {\n      pollFailures += 1;\n      if (pollFailures >= maxPollFailures) throw error;\n      await sleep(1000);\n      continue;\n    }\n    if (current.status === \"approved\") return current;\n    if (current.status === \"error\") {\n      throw new Error(current.error || \"OAuth authorization failed\");\n    }\n    if (authWindow.closed) {\n      throw new Error(\"OAuth authorization window was closed before completion\");\n    }\n    await sleep(1000);\n  }\n}\n","sourceCodeStart":41,"sourceCodeEnd":67,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/web/src/lib/mcp-dashboard-oauth.ts#L41-L67","documentation":"While polling the OAuth flow status (1s interval, up to maxPollFailures network errors tolerated), the backend reported `{status: 'error'}` with an empty error field, so the client falls back to this generic 'authorization failed' text. It means the flow genuinely failed server-side — not a network blip (those retry) — such as the provider rejecting the token exchange.","triggerScenarios":"The user completes or abandons consent and the provider returns an error to the callback; the code/token exchange at the gateway fails (bad client_secret, redirect_uri mismatch); or the flow times out server-side and is marked errored.","commonSituations":"Wrong OAuth client secret or redirect URI configured on the gateway; the provider's app not approved for the scopes; users pasting the dashboard behind a proxy that mangles the redirect.","solutions":["Check the gateway logs for the flow_id — the recorded server-side error explains the failure that the status payload omitted.","Verify the OAuth client configuration (client_id/secret, redirect URI, scopes) for the MCP server.","Retry the flow after fixing config; each retry mints a new flow_id and popup."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const flow = await completeMcpDashboardOAuth({ serverName, start, status, open })\n} catch (err) {\n  if (/authorization failed/i.test(String(err))) {\n    toast('OAuth was rejected — verify client id/secret and redirect URI, then retry')\n    return\n  }\n  throw err\n}","preventionTips":["Pre-validate OAuth client credentials and redirect URIs before starting flows.","Offer an explicit retry action; flows are cheap to restart.","Check gateway logs for the specific exchange failure behind the generic status."],"tags":["oauth","mcp","polling"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}