siyuan-note/siyuan · error

OIDC client ID is required

Error message

OIDC client ID is required

What it means

ValidateOIDCConfiguration requires a non-empty ClientID once OIDC is enabled. The client ID is the identifier issued by the OIDC provider (GitHub OAuth App, Google, Microsoft, or a custom provider) that SiYuan presents during the OAuth flow. An empty client ID means the OAuth handshake cannot even be constructed, so validation fails with "OIDC client ID is required".

Solutions

  1. Create/locate the OAuth app in your provider's console and copy its client ID into Settings - Accounts - OIDC - Client ID.
  2. If configuring programmatically, set the ClientID field on conf.OIDC before calling ValidateOIDCConfiguration.
  3. Verify the saved workspace config actually contains the client ID (it may have failed to persist).

Example fix

// before
config := &conf.OIDC{Enabled: true, Provider: conf.OIDCProviderGitHub}
// after
config := &conf.OIDC{Enabled: true, Provider: conf.OIDCProviderGitHub, ClientID: "Iv1.xxxxxxxxxxxxxxxx"}
Defensive patterns

Strategy: validation

Validate before calling

// Go: pre-validate before invoking login/validation
if cfg.ClientID == "" {
	return errors.New("set the OIDC client ID from your provider's console before login")
}

Type guard

func hasClientID(cfg *conf.OIDC) bool { return cfg != nil && strings.TrimSpace(cfg.ClientID) != "" }

Try / catch

// JavaScript caller
try {
  await startOIDCLogin();
} catch (e) {
  if (e.msg.includes("client ID is required")) {
    focusField("oidcClientID"); // send user to the empty field
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling ValidateOIDCConfiguration with config.ClientID == "" — e.g. enabling OIDC in settings but leaving the client ID field blank, or code constructing conf.OIDC programmatically without setting ClientID.

Common situations: Enabling the OIDC toggle before obtaining a client ID from the provider's developer console; pasting the client secret into the secret field and forgetting the ID; a config migration/restore that dropped the client ID.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/oidc.go:460

		return
	}
	workspaceSession := util.GetWorkspaceSession(util.GetSession(c))
	if !cancelOIDCValidation(input.PollToken, workspaceSession.OIDCBinding) {
		ret = apicontract.Failure[apicontract.Null](-1, oidcLanguage(369, "Invalid OIDC configuration"))
	}
	return
}

func validateOIDCConfiguration() error {
	return ValidateOIDCConfiguration(Conf.GetOIDC())
}

func ValidateOIDCConfiguration(config *conf.OIDC) error {
	if config == nil || !config.Enabled {
		return errors.New("OIDC login is not enabled")
	}
	if config.ClientID == "" {
		return errors.New("OIDC client ID is required")
	}
	if config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == "" {
		return errors.New("GitHub OAuth client secret is required")
	}
	if (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL == "" {
		return errors.New("OIDC issuer URL is required")
	}
	if (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL != "" {
		issuer, err := url.Parse(config.IssuerURL)
		if err != nil || issuer.Host == "" || issuer.User != nil || issuer.RawQuery != "" || issuer.Fragment != "" ||
			(issuer.Scheme != "https" && !util.IsLocalHostname(issuer.Hostname())) {
			return errors.New("OIDC issuer URL must use HTTPS unless it is a loopback address")
		}
	}
	if config.Provider != conf.OIDCProviderCustom && config.Provider != conf.OIDCProviderGoogle &&
		config.Provider != conf.OIDCProviderMicrosoft && config.Provider != conf.OIDCProviderGitHub {
		return errors.New("Unsupported OIDC provider")
	}

View on GitHub (pinned to 9f775e8a12)