siyuan-note/siyuan · error

Unsupported OIDC claim rule operator

Error message

Unsupported OIDC claim rule operator

What it means

Ninth check in ValidateOIDCConfiguration (kernel/model/oidc.go:543): a claim rule's Operator is neither OIDCClaimOperatorEquals nor OIDCClaimOperatorContains. SiYuan only supports these two match semantics, so any other operator value is rejected.

Source

Thrown at kernel/model/oidc.go:543

		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")
	}
	if !config.AllowAll && len(config.ClaimRules) == 0 {
		return errors.New("OIDC login requires at least one claim rule when Allow all users is disabled")
	}
	for _, rule := range config.ClaimRules {
		if rule == nil || rule.Claim == "" || len(rule.Values) == 0 {
			return errors.New("OIDC claim rules must include a claim and at least one value")
		}
		if rule.Operator != conf.OIDCClaimOperatorEquals && rule.Operator != conf.OIDCClaimOperatorContains {
			return errors.New("Unsupported OIDC claim rule operator")
		}
		for _, value := range rule.Values {
			if value == "" {
				return errors.New("OIDC claim rule values cannot be empty")
			}
		}
	}
	return nil
}

func ValidateOIDCMobileConfiguration(config *conf.OIDC) error {
	if err := ValidateOIDCConfiguration(config); err != nil {
		return err
	}
	if config.Provider == conf.OIDCProviderGoogle {
		return errors.New("Google does not support the fixed SiYuan mobile OIDC callback URI")
	}
	return nil

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Use 'equals' or 'contains' (the OIDCClaimOperator* constants) for every rule.
  2. Re-open the rule in the settings UI and pick one of the two supported operators.
  3. After fixing, re-validate with ValidateOIDCConfiguration.

Example fix

// before
rule.Operator = "in"
// after
rule.Operator = conf.OIDCClaimOperatorEquals
Defensive patterns

Strategy: validation

Validate before calling

switch r.Operator {
case conf.OIDCClaimOperatorEquals, conf.OIDCClaimOperatorContains:
default:
    return fmt.Errorf("unsupported operator: %%s", r.Operator)
}

Type guard

func validOperator(o conf.OIDCClaimOperator) bool {
    return o == conf.OIDCClaimOperatorEquals || o == conf.OIDCClaimOperatorContains
}

Prevention

When it happens

Trigger: Saving a claim rule with a custom/wrong operator string (e.g. '==', 'in', 'regex'); a future-version rule downgraded to an unsupported constant.

Common situations: Hand-edited JSON using arbitrary operator strings; a plugin writing rules with its own operator vocabulary; UI bug submitting a raw enum label.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/343e080ed4c4aa0d. Report an issue: GitHub.