{"record":{"id":"fcdecd61c814ef8a","repo":"siyuan-note/siyuan","slug":"oidc-issuer-url-is-required-fcdecd","errorCode":null,"errorMessage":"OIDC issuer URL is required","messagePattern":"OIDC issuer URL is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc_provider/provider.go","lineNumber":61,"sourceCode":"\t\treturn nil, errors.New(\"OIDC redirect URL is required\")\n\t}\n\tif config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == \"\" {\n\t\treturn nil, errors.New(\"GitHub OAuth client secret is required\")\n\t}\n\tissuerURL := strings.TrimSpace(config.IssuerURL)\n\tswitch config.Provider {\n\tcase conf.OIDCProviderGoogle:\n\t\tissuerURL = googleIssuer\n\tcase conf.OIDCProviderMicrosoft:\n\t\t// Microsoft 多租户端点的 issuer 会随租户变化，必须使用租户专属 issuer。\n\tcase conf.OIDCProviderCustom:\n\tcase conf.OIDCProviderGitHub:\n\t\treturn newGitHub(config, redirectURL), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported OIDC provider [%s]\", config.Provider)\n\t}\n\tif issuerURL == \"\" {\n\t\treturn nil, errors.New(\"OIDC issuer URL is required\")\n\t}\n\tdiscovered, err := oidc.NewProvider(ctx, issuerURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"discover OIDC provider failed: %w\", err)\n\t}\n\tscopes := append([]string{}, config.Scopes...)\n\tif !contains(scopes, oidc.ScopeOpenID) {\n\t\tscopes = append([]string{oidc.ScopeOpenID}, scopes...)\n\t}\n\treturn &Provider{\n\t\tkind: conf.OIDCProviderCustom,\n\t\toauth2Config: &oauth2.Config{\n\t\t\tClientID:     config.ClientID,\n\t\t\tClientSecret: config.ClientSecret,\n\t\t\tEndpoint:     discovered.Endpoint(),\n\t\t\tRedirectURL:  redirectURL,\n\t\t\tScopes:       scopes,\n\t\t},","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/oidc_provider/provider.go#L43-L79","documentation":"After resolving the issuer URL (explicitly configured, or defaulted for Google/Microsoft), New requires it to be non-empty before attempting OIDC discovery. Only the Custom provider can leave IssuerURL empty in the config, so this error means a custom-provider configuration was saved without the issuer endpoint. Discovery cannot proceed without a base issuer URL.","triggerScenarios":"Calling New with config.Provider == conf.OIDCProviderCustom and strings.TrimSpace(config.IssuerURL) == \"\" — i.e. the Custom OIDC provider selected but the issuer URL field left blank.","commonSituations":"Admin selected \"Custom\" in the settings dialog but skipped the IssuerURL field; whitespace-only value pasted into the field; config JSON hand-edited and the key dropped; issuer URL cleared during troubleshooting and the config saved anyway.","solutions":["Set IssuerURL in the OIDC config to the IdP's issuer base URL (e.g. https://accounts.example.com), typically the value in the IdP's .well-known/openid-configuration location minus the well-known suffix.","Trim or remove whitespace-only values; the code trims but rejects blank strings.","Validate the issuer URL field as required whenever provider == custom in the settings UI.","If you meant a hosted provider, switch config.Provider to Google/Microsoft/GitHub which have built-in issuers."],"exampleFix":"// before\ncfg := &conf.OIDC{Provider: conf.OIDCProviderCustom, IssuerURL: \"\"}\nprovider, err := New(cfg, redirectURL)\n// after\ncfg := &conf.OIDC{Provider: conf.OIDCProviderCustom, IssuerURL: \"https://sso.example.com/realms/main\"}\nprovider, err := New(cfg, redirectURL)","handlingStrategy":"validation","validationCode":"if cfg.Provider == conf.OIDCProviderCustom && strings.TrimSpace(cfg.IssuerURL) == \"\" {\n    return errors.New(\"issuer URL is required for the custom OIDC provider\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"issuer URL is required\") {\n        // mark the IssuerURL field as the offending setting\n    }\n    return err\n}","preventionTips":["Mark IssuerURL required in the UI whenever provider == custom","Validate the issuer by fetching .well-known/openid-configuration at config-save time","Trim user input before persisting so whitespace-only values are rejected early"],"tags":["oidc","configuration","issuer-url","validation"],"backgroundTag":"missing-required-config-field","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"}