usememos/memos · error
config.oauth2Config.scopes is required
Error message
config.oauth2Config.scopes is required
What it means
Thrown when the oauth2Config block of an identity-provider deployment file has an empty or missing "scopes" array. OAuth2 authorization requests need at least one scope; the deployment validator treats an empty list as a misconfiguration and fails startup rather than applying a provider that could never complete an auth flow.
Source
Thrown at store/deployment_config.go:209
if strings.TrimSpace(field.value) == "" {
return errors.Errorf("config.oauth2Config.%s is required", field.name)
}
}
for _, field := range []struct {
name string
value string
}{
{name: "authUrl", value: config.AuthUrl},
{name: "tokenUrl", value: config.TokenUrl},
{name: "userInfoUrl", value: config.UserInfoUrl},
} {
parsed, err := url.ParseRequestURI(field.value)
if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") || parsed.Host == "" {
return errors.Errorf("config.oauth2Config.%s must be an absolute HTTP(S) URL", field.name)
}
}
if len(config.Scopes) == 0 {
return errors.New("config.oauth2Config.scopes is required")
}
for i, scope := range config.Scopes {
if strings.TrimSpace(scope) == "" {
return errors.Errorf("config.oauth2Config.scopes[%d] must not be empty", i)
}
}
if config.FieldMapping == nil || strings.TrimSpace(config.FieldMapping.Identifier) == "" {
return errors.New("config.oauth2Config.fieldMapping.identifier is required")
}
return nil
}
func validateAndNormalizeDeploymentInstanceSetting(setting *storepb.InstanceSetting) error {
switch setting.Key {
case storepb.InstanceSettingKey_GENERAL:
if setting.GetGeneralSetting() == nil {
return errors.New("generalSetting must be populated for key GENERAL")
}View on GitHub (pinned to 14d757ce1f)
Solutions
- Add the provider's scopes, e.g. "scopes": ["openid", "profile", "email"] under config.oauth2Config.
- Check the upstream provider's docs for the minimal scope set that exposes the identifier field used in fieldMapping.
Example fix
// before
"oauth2Config": { "clientId": "...", "authUrl": "...", "tokenUrl": "...", "userInfoUrl": "...", "fieldMapping": { ... } }
// after
"oauth2Config": { "clientId": "...", "authUrl": "...", "tokenUrl": "...", "userInfoUrl": "...", "scopes": ["openid", "profile", "email"], "fieldMapping": { ... } } Defensive patterns
Strategy: validation
Validate before calling
cfg := provider.Config.GetOauth2Config()
if len(cfg.Scopes) == 0 {
return errors.New("config.oauth2Config.scopes must not be empty")
} Type guard
func hasScopes(cfg *storepb.OAuth2Config) bool {
ok := len(cfg.GetScopes()) > 0
for _, s := range cfg.GetScopes() {
ok = ok && strings.TrimSpace(s) != ""
}
return ok
} Prevention
- Look up the provider's minimal scope set in its OAuth docs before writing the file.
- Include scopes in any example/template so they are not dropped when copying.
When it happens
Trigger: config.oauth2Config in a memos-idp-*.json with no "scopes" key, "scopes": [], or scopes containing only whitespace strings (that variant produces the scopes[i] error instead).
Common situations: Providers like generic OIDC where the author omitted scopes; migrating a DB-stored provider whose scopes list was empty; assuming the server injects a default scope.
Related errors
- config.oauth2Config is required
- config.oauth2Config.fieldMapping.identifier is required
- uid is invalid
- name is required
- type must be OAUTH2
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/4bc5c0b0e724fcec.
Report an issue: GitHub.