siyuan-note/siyuan · error

register OAuth client

Error message

register OAuth client: %w

What it means

Wraps a failure from oauthex.RegisterClient, the RFC 7591 dynamic client registration POST to asm.RegistrationEndpoint. The library wraps the underlying error so callers can distinguish registration failures from metadata, token, or consent failures during Authorize.

Solutions

  1. Read the wrapped error: if it is an OAuth error response (e.g. invalid_redirect_uri, invalid_client_metadata), align the server's registration policy with the client's metadata (loopback redirect, authorization_code + refresh_token, requested scopes)
  2. If DCR requires an initial access token, either provide one or use an IdP with open DCR
  3. Check connectivity/auth to the registration endpoint (curl -i the URL)
  4. Retry later if the wrapped error indicates rate limiting (429)
Defensive patterns

Strategy: try-catch

Try / catch

if err := h.Authorize(ctx, req, resp); err != nil {
    if strings.Contains(err.Error(), "register OAuth client:") {
        // inspect wrapped RFC 7591 error code (invalid_redirect_uri, etc.)
        logRegistrationFailure(err)
    }
}

Prevention

When it happens

Trigger: Interactive Authorize reaches dynamic registration (no reusable registration, RegistrationEndpoint set, compatible auth method) and RegisterClient fails: non-2xx from the registration endpoint (400/401/403/429), invalid JSON, or a network failure.

Common situations: DCR endpoint requires an initial access token the client does not send; registration policy rejects the requested scopes/grant types or the loopback redirect URI; server rate-limits registrations; registration endpoint behind auth/proxy; server returns HTML error pages.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/4f537c3b56f133ba. Report an issue: GitHub.

Appendix: source

Thrown at kernel/mcp/client/oauth.go:307

		tokenAuthMethod := preferredTokenAuthMethod(asm.TokenEndpointAuthMethodsSupported)
		if len(asm.TokenEndpointAuthMethodsSupported) > 0 && tokenAuthMethod == "" {
			return fmt.Errorf("OAuth authorization server does not support a compatible token endpoint authentication method")
		}
		grantTypes := []string{"authorization_code"}
		if len(asm.GrantTypesSupported) == 0 || slices.Contains(asm.GrantTypesSupported, "refresh_token") {
			grantTypes = append(grantTypes, "refresh_token")
		}
		registration, registerErr := oauthex.RegisterClient(ctx, asm.RegistrationEndpoint, &oauthex.ClientRegistrationMetadata{
			RedirectURIs:            []string{callbackURL},
			TokenEndpointAuthMethod: tokenAuthMethod,
			GrantTypes:              grantTypes,
			ResponseTypes:           []string{"code"},
			ClientName:              "SiYuan",
			Scope:                   strings.Join(scopes, " "),
			ApplicationType:         "native",
		}, h.client)
		if registerErr != nil {
			return fmt.Errorf("register OAuth client: %w", registerErr)
		}
		registrationCredential = oauthCredential{
			ServerID:            h.server.ID,
			Endpoint:            h.server.URL,
			Resource:            prm.Resource,
			Issuer:              asm.Issuer,
			ResourceMetadataURL: prm.MetadataURL,
			RedirectURL:         callbackURL,
			ClientID:            registration.ClientID,
			ClientSecret:        registration.ClientSecret,
			ClientSecretExpiry:  registration.ClientSecretExpiresAt,
			TokenEndpoint:       asm.TokenEndpoint,
			RevocationEndpoint:  asm.RevocationEndpoint,
			TokenAuthMethod:     registration.TokenEndpointAuthMethod,
			Scopes:              scopes,
		}
		if registrationCredential.TokenAuthMethod == "" {
			if registration.ClientSecret == "" {

View on GitHub (pinned to 9f775e8a12)