{"record":{"id":"38800b733d4231a3","repo":"different-ai/openwork","slug":"the-mcp-provider-did-not-return-an-authorization-u","errorCode":null,"errorMessage":"The MCP provider did not return an authorization URL.","messagePattern":"The MCP provider did not return an authorization URL\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/mcp-connections-screen.tsx","lineNumber":436,"sourceCode":"      const connection = result.data?.find((entry) => entry.id === connectionId);\n      if (connection?.connected || Date.now() - startedAt > OAUTH_POLL_TIMEOUT_MS) {\n        stopPolling();\n      }\n    }, OAUTH_POLL_INTERVAL_MS);\n  }\n\n  async function handleConnectOAuth(connectionId: string, pendingAuthorizationWindow?: Window) {\n    setConnectionActionError(null);\n    let authorizationWindow: Window | null = pendingAuthorizationWindow ?? null;\n    try {\n      authorizationWindow = authorizationWindow ?? openMcpAuthorizationWindow();\n      const result = await startOAuth.mutateAsync(connectionId);\n      if (result.status === \"connected\") {\n        authorizationWindow.close();\n        void refetch();\n        return;\n      }\n      if (!result.authorizeUrl) throw new Error(\"The MCP provider did not return an authorization URL.\");\n      authorizationWindow.location.href = safeMcpAuthorizationUrl(result.authorizeUrl);\n      pollUntilConnected(connectionId);\n    } catch (connectError) {\n      const message = connectError instanceof Error ? connectError.message : \"Failed to connect the MCP server.\";\n      showMcpAuthorizationError(authorizationWindow, {\n        message,\n        ...(connectError instanceof McpOAuthStartError\n          ? { details: connectError.details }\n          : {}),\n      });\n      if (connectError instanceof McpOAuthConfigurationRequiredError) {\n        setOAuthClientConfigurationRequiredIds((current) => current.includes(connectionId)\n          ? current\n          : [...current, connectionId]);\n        return;\n      }\n      setConnectionActionError({\n        connectionId,","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/mcp-connections-screen.tsx#L418-L454","documentation":"handleConnectOAuth starts the MCP OAuth flow via startOAuth.mutateAsync; when the server reports a status other than \"connected\" it must supply `authorizeUrl` to redirect the popup to. If `authorizeUrl` is missing/empty the flow cannot continue, so this error is thrown and surfaced in the authorization window.","triggerScenarios":"`startOAuth` mutation resolved (HTTP 200) but the response body lacks `authorizeUrl` — server-side provider metadata could not be built, the MCP server's authorization_endpoint is unknown, or the connection was deleted between calls.","commonSituations":"MCP server registered without valid OAuth discovery (no .well-known/oauth-authorization-server); provider rejects dynamic client registration server-side; stale connection row pointing at a dead MCP server; clock/auth issues causing the server to bail before producing a URL.","solutions":["Inspect the startOAuth network response — check for server-side error fields explaining why no URL was produced","Verify the MCP server exposes valid OAuth discovery metadata (well-known endpoints) and an authorization endpoint","Delete and recreate the MCP connection, then retry the connect flow","Check server logs on den-api for errors during the OAuth start step"],"exampleFix":"// before\nif (!result.authorizeUrl) throw new Error(\"The MCP provider did not return an authorization URL.\");\n// after\nif (!result.authorizeUrl) {\n  console.error('startOAuth response', result);\n  throw new Error(`No authorizeUrl (status=${result.status}). Check MCP server OAuth discovery metadata.`);\n}","handlingStrategy":"validation","validationCode":"const result = await startOAuth.mutateAsync(connectionId);\nif (result.status !== \"connected\" && typeof result.authorizeUrl !== \"string\") {\n  // abort before opening the popup, or close it with a friendly message\n  authorizationWindow.close();\n  return;\n}","typeGuard":"const hasAuthorizeUrl = (r: { status: string; authorizeUrl?: string }): r is { status: string; authorizeUrl: string } =>\n  typeof r.authorizeUrl === \"string\" && r.authorizeUrl.length > 0;","tryCatchPattern":"try {\n  const result = await startOAuth.mutateAsync(connectionId);\n  if (!result.authorizeUrl) throw new Error(\"The MCP provider did not return an authorization URL.\");\n} catch (e) {\n  showMcpAuthorizationError(authorizationWindow, { message: e instanceof Error ? e.message : 'OAuth start failed' });\n}","preventionTips":["Validate the MCP server's OAuth discovery metadata before saving the connection","Check result.status explicitly before relying on authorizeUrl","Close or never open the popup until a valid URL exists","Monitor server logs for dynamic-client-registration failures"],"tags":["oauth","mcp","authorization","api-response"],"backgroundTag":"oauth-flow-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}