{"record":{"id":"b3bf622a9f0a57d7","repo":"siyuan-note/siyuan","slug":"oidc-claim-rule-values-cannot-be-empty","errorCode":null,"errorMessage":"OIDC claim rule values cannot be empty","messagePattern":"OIDC claim rule values cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc.go","lineNumber":491,"sourceCode":"\t\t}\n\t}\n\tif config.Provider != conf.OIDCProviderCustom && config.Provider != conf.OIDCProviderGoogle &&\n\t\tconfig.Provider != conf.OIDCProviderMicrosoft && config.Provider != conf.OIDCProviderGitHub {\n\t\treturn errors.New(\"Unsupported OIDC provider\")\n\t}\n\tif !config.AllowAll && len(config.ClaimRules) == 0 {\n\t\treturn errors.New(\"OIDC login requires at least one claim rule when Allow all users is disabled\")\n\t}\n\tfor _, rule := range config.ClaimRules {\n\t\tif rule == nil || rule.Claim == \"\" || len(rule.Values) == 0 {\n\t\t\treturn errors.New(\"OIDC claim rules must include a claim and at least one value\")\n\t\t}\n\t\tif rule.Operator != conf.OIDCClaimOperatorEquals && rule.Operator != conf.OIDCClaimOperatorContains {\n\t\t\treturn errors.New(\"Unsupported OIDC claim rule operator\")\n\t\t}\n\t\tfor _, value := range rule.Values {\n\t\t\tif value == \"\" {\n\t\t\t\treturn errors.New(\"OIDC claim rule values cannot be empty\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ValidateOIDCMobileConfiguration(config *conf.OIDC) error {\n\tif err := ValidateOIDCConfiguration(config); err != nil {\n\t\treturn err\n\t}\n\tif config.Provider == conf.OIDCProviderGoogle {\n\t\treturn errors.New(\"Google does not support the fixed SiYuan mobile OIDC callback URI\")\n\t}\n\treturn nil\n}\n\nfunc ValidateOIDCProviderConfiguration(ctx context.Context, config *conf.OIDC) error {\n\tif err := ValidateOIDCConfiguration(config); err != nil {","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/oidc.go#L473-L509","documentation":"Thrown by ValidateOIDCConfiguration when a claim rule in config.ClaimRules is nil, has an empty Claim name, or carries an empty Values list. Each rule must name a claim and at least one matching value to gate login; a rule object with missing claim name or no values is the faulting input (a sibling check enforces at least one rule when AllowAll is off).","triggerScenarios":"A rule passes claim/operator checks but one of its Values entries is \"\" (e.g. Values: []string{\"admin\", \"\"}).","commonSituations":"Trailing empty value left in a comma-separated input field; user clears a value chip without removing the row; CSV import produces empty fields.","solutions":["Remove empty strings from the rule's Values array","Trim whitespace and drop blank entries before building the rule","In the UI, delete the emptied value row instead of saving it blank"],"exampleFix":"// before\nValues: []string{\"admin\", \"\"}\n// after\nValues: []string{\"admin\"}","handlingStrategy":"validation","validationCode":"rules.forEach(r => { r.values = (r.values || []).map(v => (v || '').trim()).filter(v => v.length > 0); });","typeGuard":"const hasOnlyNonEmptyValues = (r) => r.Values.every(v => typeof v === 'string' && v.trim() !== '');","tryCatchPattern":"if err := ValidateOIDCConfiguration(cfg); err != nil {\n    if strings.Contains(err.Error(), \"values cannot be empty\") { /* sanitize Values */ }\n}","preventionTips":["Trim and filter values when parsing user input (CSV, comma-separated fields)","Remove value chips atomically in the UI","Sanitize arrays before persisting config"],"tags":["oidc","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}