{"record":{"id":"c3678203d7009b7e","repo":"siyuan-note/siyuan","slug":"oidc-client-id-is-required","errorCode":null,"errorMessage":"OIDC client ID is required","messagePattern":"OIDC client ID is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc.go","lineNumber":460,"sourceCode":"\t\treturn\n\t}\n\tworkspaceSession := util.GetWorkspaceSession(util.GetSession(c))\n\tif !cancelOIDCValidation(input.PollToken, workspaceSession.OIDCBinding) {\n\t\tret = apicontract.Failure[apicontract.Null](-1, oidcLanguage(369, \"Invalid OIDC configuration\"))\n\t}\n\treturn\n}\n\nfunc validateOIDCConfiguration() error {\n\treturn ValidateOIDCConfiguration(Conf.GetOIDC())\n}\n\nfunc ValidateOIDCConfiguration(config *conf.OIDC) error {\n\tif config == nil || !config.Enabled {\n\t\treturn errors.New(\"OIDC login is not enabled\")\n\t}\n\tif config.ClientID == \"\" {\n\t\treturn errors.New(\"OIDC client ID is required\")\n\t}\n\tif config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == \"\" {\n\t\treturn errors.New(\"GitHub OAuth client secret is required\")\n\t}\n\tif (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL == \"\" {\n\t\treturn errors.New(\"OIDC issuer URL is required\")\n\t}\n\tif (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL != \"\" {\n\t\tissuer, err := url.Parse(config.IssuerURL)\n\t\tif err != nil || issuer.Host == \"\" || issuer.User != nil || issuer.RawQuery != \"\" || issuer.Fragment != \"\" ||\n\t\t\t(issuer.Scheme != \"https\" && !util.IsLocalHostname(issuer.Hostname())) {\n\t\t\treturn errors.New(\"OIDC issuer URL must use HTTPS unless it is a loopback address\")\n\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}","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/oidc.go#L442-L478","documentation":"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\".","triggerScenarios":"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.","commonSituations":"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.","solutions":["Create/locate the OAuth app in your provider's console and copy its client ID into Settings - Accounts - OIDC - Client ID.","If configuring programmatically, set the ClientID field on conf.OIDC before calling ValidateOIDCConfiguration.","Verify the saved workspace config actually contains the client ID (it may have failed to persist)."],"exampleFix":"// before\nconfig := &conf.OIDC{Enabled: true, Provider: conf.OIDCProviderGitHub}\n// after\nconfig := &conf.OIDC{Enabled: true, Provider: conf.OIDCProviderGitHub, ClientID: \"Iv1.xxxxxxxxxxxxxxxx\"}","handlingStrategy":"validation","validationCode":"// Go: pre-validate before invoking login/validation\nif cfg.ClientID == \"\" {\n\treturn errors.New(\"set the OIDC client ID from your provider's console before login\")\n}","typeGuard":"func hasClientID(cfg *conf.OIDC) bool { return cfg != nil && strings.TrimSpace(cfg.ClientID) != \"\" }","tryCatchPattern":"// JavaScript caller\ntry {\n  await startOIDCLogin();\n} catch (e) {\n  if (e.msg.includes(\"client ID is required\")) {\n    focusField(\"oidcClientID\"); // send user to the empty field\n  } else { throw e; }\n}","preventionTips":["Copy the client ID from the provider console before enabling OIDC","Mark client ID as required in any custom setup tooling","Verify config persistence after saving settings","Validate the whole OIDC block (ValidateOIDCConfiguration) right after configuration changes"],"tags":["oidc","configuration","missing-field"],"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"}