usememos/memos · error

config.oauth2Config is required

Error message

config.oauth2Config is required

What it means

Thrown when an identity-provider deployment file has no "config" message or its config does not carry the oauth2Config oneof member (config.GetOauth2Config() returns nil). Since the file loader only supports type OAUTH2, the oauth2Config block is mandatory: it holds clientId, clientSecret, authUrl, tokenUrl, userInfoUrl, scopes and fieldMapping. Startup aborts with 'invalid identity provider deployment file'.

Source

Thrown at store/deployment_config.go:178

		return errors.New("id must be omitted")
	}
	if !base.UIDMatcher.MatchString(provider.Uid) {
		return errors.New("uid is invalid")
	}
	if strings.TrimSpace(provider.Name) == "" {
		return errors.New("name is required")
	}
	if provider.Type != storepb.IdentityProvider_OAUTH2 {
		return errors.New("type must be OAUTH2")
	}
	if provider.IdentifierFilter != "" {
		if _, err := regexp.Compile(provider.IdentifierFilter); err != nil {
			return errors.Wrap(err, "identifierFilter must be a valid regular expression")
		}
	}
	config := provider.Config.GetOauth2Config()
	if config == nil {
		return errors.New("config.oauth2Config is required")
	}
	required := []struct {
		name  string
		value string
	}{
		{name: "clientId", value: config.ClientId},
		{name: "clientSecret", value: config.ClientSecret},
		{name: "authUrl", value: config.AuthUrl},
		{name: "tokenUrl", value: config.TokenUrl},
		{name: "userInfoUrl", value: config.UserInfoUrl},
	}
	for _, field := range required {
		if strings.TrimSpace(field.value) == "" {
			return errors.Errorf("config.oauth2Config.%s is required", field.name)
		}
	}
	for _, field := range []struct {
		name  string

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Wrap the OAuth fields: add "config": { "oauth2Config": { ... } } to the memos-idp-*.json file.
  2. Check the key spelling and casing exactly: config.oauth2Config (protojson lowerCamelCase).
  3. Validate the file renders the full structure if it is templated.

Example fix

// before
{ "uid": "github", "name": "GitHub", "type": "OAUTH2",
  "config": { "clientId": "...", "authUrl": "..." } }

// after
{ "uid": "github", "name": "GitHub", "type": "OAUTH2",
  "config": { "oauth2Config": {
    "clientId": "...", "clientSecret": "...",
    "authUrl": "...", "tokenUrl": "...", "userInfoUrl": "...",
    "scopes": ["read:user"],
    "fieldMapping": { "identifier": "login" }
  } } }
Defensive patterns

Strategy: validation

Validate before calling

if provider.Config == nil || provider.Config.GetOauth2Config() == nil {
    return errors.New("idp config.oauth2Config is required")
}

Type guard

func hasOauth2Config(c *storepb.IdentityProviderConfig) bool {
    return c != nil && c.GetOauth2Config() != nil
}

Prevention

When it happens

Trigger: A memos-idp-*.json with "config": {} or no "config" key at all, or with a typo'd key like "oauthConfig" or "oauth2config" that protojson silently ignores (unknown fields produce a separate error, but wrong-cased oneof members may leave the message empty).

Common situations: Hand-writing the JSON and nesting the OAuth fields directly under "config" instead of under "config.oauth2Config"; using snake_case "oauth2_config" inconsistently; copying from docs that show only the inner fields.

Related errors


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