siyuan-note/siyuan · error
Unsupported OIDC claim rule operator
Error message
Unsupported OIDC claim rule operator
What it means
Claim rule operators are restricted to the whitelisted set conf.OIDCClaimOperatorEquals and conf.OIDCClaimOperatorContains; any other operator string is rejected because the login check cannot evaluate it.
Solutions
- Set rule.Operator to conf.OIDCClaimOperatorEquals ("equals") for exact matching
- Or use conf.OIDCClaimOperatorContains ("contains") for substring/list-contains matching
- Check the constant values in kernel/conf to send the exact expected string over the API
Example fix
// before rule.Operator = "regex" // after rule.Operator = conf.OIDCClaimOperatorContains
Defensive patterns
Strategy: validation
Validate before calling
const ops = ['equals', 'contains']; const ok = rules.every(r => ops.includes(r.operator));
Type guard
const isKnownOperator = (op) => op === conf.OIDCClaimOperatorEquals || op === conf.OIDCClaimOperatorContains;
Try / catch
if err := ValidateOIDCConfiguration(cfg); err != nil {
if strings.Contains(err.Error(), "operator") { /* reset operator to a supported constant */ }
} Prevention
- Only use the exported conf.OIDCClaimOperator* constants, never raw strings
- Render the operator as a fixed dropdown instead of free text
- Re-check constants when upgrading SiYuan versions
When it happens
Trigger: ValidateOIDCConfiguration encounters a rule whose Operator differs from both OIDCClaimOperatorEquals and OIDCClaimOperatorContains (e.g. misspelled or custom operator value sent via the settings API).
Common situations: Hand-editing the config JSON with an operator like 'regex' or 'eq'; upgrading from an older/other schema with different operator names; typos when constructing rules programmatically.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- ErrInvalidColumnAlign
- Field [mode] must be 0 or 1
- Field [ ] has an invalid value
- invalid asset download mode
- invalid block ref check scope
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/343e080ed4c4aa0d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/oidc.go:487
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 nilView on GitHub (pinned to 9f775e8a12)