Tencent/WeKnora · error

MCP service does not use OAuth

Error message

MCP service %s does not use OAuth

What it means

Returned by StartAuthorization when the service's AuthConfig is not OAuth-based. Only services configured with OAuth auth can run the authorization-code flow; attempting to start one for a service using another auth type (API key, none, etc.) is rejected with the service ID in the message.

Solutions

  1. Switch the service's AuthConfig to OAuth before calling StartAuthorization
  2. Update the client to only render/start OAuth flows when the service auth type is oauth
  3. Check whether a stale service record was fetched; reload the service before the call
  4. Route API-key/bearer services through their own credential flow instead

Example fix

// before
url, id, err := manager.StartAuthorizationForService(ctx, svc, tenantID, principal, redirect, "")
// after
if !svc.AuthConfig.IsOAuth() {
    return fmt.Errorf("service %s uses %s auth; use the non-OAuth flow", svc.ID, svc.AuthConfig.Type)
}
url, id, err := manager.StartAuthorizationForService(ctx, svc, tenantID, principal, redirect, "")
Defensive patterns

Strategy: validation

Validate before calling

if !svc.AuthConfig.IsOAuth() {
    return fmt.Errorf("service %s uses non-OAuth auth; choose the matching flow", svc.ID)
}

Type guard

func isOAuthService(svc *types.MCPService) bool { return svc != nil && svc.AuthConfig.IsOAuth() }

Try / catch

if !isOAuthService(svc) { return useAlternativeAuthFlow(svc) }
if _, _, err := mgr.StartAuthorizationForService(ctx, svc, tenantID, principal, redirect, ""); err != nil {
    if strings.Contains(err.Error(), "does not use OAuth") { return useAlternativeAuthFlow(svc) }
    return err
}

Prevention

When it happens

Trigger: Calling AuthorizeURL or StartAuthorizationForService on a service whose AuthConfig.IsOAuth() returns false (e.g. auth type is api_key, bearer, or none).

Common situations: Frontend shows the 'Connect with OAuth' button for all services regardless of auth type; service auth type changed after deployment but cached client state still treats it as OAuth; copy/paste of OAuth setup code applied to an API-key service.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/2a42248f6d75d872. Report an issue: GitHub.

Appendix: source

Thrown at internal/mcp/oauth_manager.go:90

	}
	h := transport.NewOAuthHandler(cfg)
	h.SetBaseURL(*service.URL)
	return h, nil
}

// StartAuthorization performs discovery + (one-time) dynamic client
// registration, then returns the authorization URL and an opaque attempt ID.
// redirectURI is the backend callback URL registered with the auth server;
// frontendRedirect is where the callback bounces the browser when finished.
func (m *OAuthManager) StartAuthorization(
	ctx context.Context,
	service *types.MCPService,
	tenantID uint64,
	principal types.Principal,
	redirectURI, frontendRedirect string,
) (authorizationURL, attemptID string, err error) {
	if !service.AuthConfig.IsOAuth() {
		return "", "", fmt.Errorf("MCP service %s does not use OAuth", service.ID)
	}
	principal = principal.Normalize()
	if !principal.Valid() {
		return "", "", fmt.Errorf("principal context is required to authorize OAuth MCP service %s", service.ID)
	}

	h, err := m.newHandler(ctx, service, tenantID, principal, redirectURI)
	if err != nil {
		return "", "", err
	}

	// Register a client dynamically if we don't have one yet for this service.
	existing, _ := m.repo.GetClient(ctx, tenantID, service.ID)
	if existing == nil {
		if err := h.RegisterClient(ctx, clientRegistrationName); err != nil {
			return "", "", fmt.Errorf("dynamic client registration failed: %w", err)
		}
		clientID := h.GetClientID()

View on GitHub (pinned to 988cbb0330)