Tencent/WeKnora · error

OAuth repository is required for OAuth MCP services

Error message

OAuth repository is required for OAuth MCP services

What it means

buildOAuthConfig requires an OAuth repository to hold dynamically-registered OAuth clients and per-user tokens. When the service's AuthConfig is OAuth but ClientConfig.OAuthRepo is nil, the client cannot persist tokens, so it refuses to construct rather than failing later mid-flow.

Source

Thrown at internal/mcp/client.go:259

			*config.Service.URL,
			oauthConfig,
		)
	}
	mcpClient.OnConnectionLost(instance.onConnectionLost)
	return instance, nil
}

// buildOAuthConfig returns the OAuth configuration for an OAuth-enabled MCP
// service, or (_, false, nil) when the service does not use OAuth. It loads
// the dynamically-registered client_id and wires a per-user token store so
// the transport injects the invoking user's bearer token and refreshes it.
func buildOAuthConfig(config *ClientConfig, httpClient *http.Client) (transport.OAuthConfig, bool, error) {
	svc := config.Service
	if !svc.AuthConfig.IsOAuth() {
		return transport.OAuthConfig{}, false, nil
	}
	if config.OAuthRepo == nil {
		return transport.OAuthConfig{}, false, fmt.Errorf("OAuth repository is required for OAuth MCP services")
	}
	principal := config.Principal.Normalize()
	if !principal.Valid() && config.UserID != "" {
		principal = types.Principal{Type: types.PrincipalWebUser, ID: config.UserID}.Normalize()
	}
	if !principal.Valid() {
		return transport.OAuthConfig{}, false, fmt.Errorf("principal context is required to connect to an OAuth MCP service")
	}
	config.Principal = principal

	oauthCfg := transport.OAuthConfig{
		Scopes:                svc.AuthConfig.Scopes,
		TokenStore:            newManagedTokenStore(config.OAuthRepo, config.TenantID, principal, svc.ID),
		PKCEEnabled:           true,
		AuthServerMetadataURL: svc.AuthConfig.AuthServerMetadataURL,
		HTTPClient:            httpClient,
	}
	if regClient, err := config.OAuthRepo.GetClient(context.Background(), config.TenantID, svc.ID); err == nil && regClient != nil {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Pass a non-nil OAuthRepo in ClientConfig when the service uses OAuth auth
  2. Initialize the OAuth repository before building the client (DI container / store bootstrap)
  3. Or remove the OAuth auth strategy from the service if token-based OAuth is not intended

Example fix

// before
cfg := &ClientConfig{Service: svc, TenantID: tid, Principal: p} // OAuthRepo missing
// after
cfg := &ClientConfig{Service: svc, TenantID: tid, Principal: p, OAuthRepo: oauthRepo}
if svc.AuthConfig.IsOAuth() && cfg.OAuthRepo == nil {
    return nil, fmt.Errorf("OAuthRepo must be set for OAuth services")
}
Defensive patterns

Strategy: validation

Validate before calling

func requireOAuthRepo(cfg *ClientConfig) error {
    if cfg.Service != nil && cfg.Service.AuthConfig.IsOAuth() && cfg.OAuthRepo == nil {
        return errors.New("OAuthRepo is required for OAuth MCP services")
    }
    return nil
}

Type guard

func needsOAuthRepo(cfg *ClientConfig) bool {
    return cfg != nil && cfg.Service != nil && cfg.Service.AuthConfig.IsOAuth()
}

Try / catch

_, err := NewMCPClient(cfg)
if err != nil && strings.Contains(err.Error(), "OAuth repository is required") {
    return fmt.Errorf("dependency wiring bug: OAuthRepo not provided for OAuth service %s", cfg.Service.ID)
}

Prevention

When it happens

Trigger: NewMCPClient called for a service whose AuthConfig.IsOAuth() is true while config.OAuthRepo was left nil.

Common situations: Caller wired up the ClientConfig without the OAuth repository dependency (DI not initialized in tests/CLI tools); OAuth enabled on the service after the calling code was written; test harness constructing ClientConfig by hand without the repo.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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