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

  1. Add the provider's scopes, e.g. "scopes": ["openid", "profile", "email"] under config.oauth2Config.
  2. 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

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


AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15). Data as JSON: /api/errors/4bc5c0b0e724fcec. Report an issue: GitHub.