different-ai/openwork · error

The OAuth provider requested authorization without an author

Error message

The OAuth provider requested authorization without an authorization URL.

What it means

During connect(), the MCP SDK's auth() flow returned "REDIRECT" (the provider wants the user sent to an authorization page), but the provider's authorizeUrl was never set (null). The client cannot redirect the user without a URL, so it throws a plain Error which is then wrapped by runOperation. This indicates the OAuth provider's redirect flow completed inconsistently — authorization was requested but no authorization endpoint URL was produced.

Source

Thrown at packages/enterprise-mcp-client/src/enterprise-mcp-client.ts:492

            // servers are allowed to expose resources and/or prompts without
            // implementing tools/list at all.
            if (session.client.getServerCapabilities()?.tools) {
              await session.client.listTools(undefined, session.requestOptions)
            }
            // OAuth connections must not be treated as member-connected merely
            // because a provider exposes protocol negotiation and tools/list publicly.
            // When no member credential exists, proactively run OAuth discovery
            // so providers such as BigQuery can return an authorization URL
            // without first issuing an MCP-level 401 challenge.
            if (session.oauthProvider && !hadOAuthCredential) {
              const authResult = await auth(session.oauthProvider, {
                serverUrl: session.serverUrl,
                fetchFn: session.observer.fetch,
              })
              const authorizeUrl = session.oauthProvider.authorizeUrl
              if (authResult === "REDIRECT") {
                if (!authorizeUrl) {
                  throw new Error("The OAuth provider requested authorization without an authorization URL.")
                }
                try {
                  await closeWithinDeadline(() => session.client.close(), closeTimeoutMs)
                } catch {
                  // The bounded cleanup attempt must not discard a valid authorization URL.
                }
                return { status: "needs_auth", authorizeUrl }
              }
            }
            try {
              await closeWithinDeadline(() => session.client.close(), closeTimeoutMs)
            } catch (error) {
              throw new EnterpriseMcpClientError({
                operationPhase: "shutdown",
                requestPhase: session.observer.lastRequestPhase(),
                cause: error,
              })
            }

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect the authorization server metadata (/.well-known/oauth-authorization-server) for the provider and confirm authorization_endpoint is present.
  2. Update @modelcontextprotocol/client and @modelcontextprotocol/core to matching versions so auth() sets authorizeUrl before returning REDIRECT.
  3. Retry the connect; if intermittent, capture the provider response to confirm whether metadata discovery partially failed.
  4. Report/patch the provider: a REDIRECT result without an authorize URL is a contract violation on the provider side.
Defensive patterns

Strategy: retry

Validate before calling

const res = await fetch(authorizationServerUrl.replace(/\/$/, "") + "/.well-known/oauth-authorization-server");
const meta = await res.json();
if (!meta.authorization_endpoint) throw new Error("Provider metadata lacks authorization_endpoint — REDIRECT will fail.");

Type guard

function hasAuthorizeUrl(p: { authorizeUrl: string | null }): p is { authorizeUrl: string } {
  return typeof p.authorizeUrl === "string" && p.authorizeUrl.length > 0;
}

Try / catch

try {
  await client.connect(input);
} catch (e) {
  if (String(e.cause?.message).includes("without an authorization URL")) {
    // provider metadata defect — refresh metadata and retry once, then surface to admin
  }
  throw e;
}

Prevention

When it happens

Trigger: auth(session.oauthProvider, ...) resolves with "REDIRECT" while session.oauthProvider.authorizeUrl is null — i.e. redirectToAuthorization was never invoked before the REDIRECT result, typically due to an SDK version mismatch or a provider metadata bug where the authorization endpoint is missing.

Common situations: Authorization server metadata lacking an authorization_endpoint; a broken/misconfigured provider behind a gateway; upgrading @modelcontextprotocol packages so auth() semantics diverge from the provider's expectations.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/50b19840ed8fddda. Report an issue: GitHub.