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 stringView on GitHub (pinned to 14d757ce1f)
Solutions
- Wrap the OAuth fields: add "config": { "oauth2Config": { ... } } to the memos-idp-*.json file.
- Check the key spelling and casing exactly: config.oauth2Config (protojson lowerCamelCase).
- 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
- Keep a known-good memos-idp-*.json example in the repo and start from it.
- Remember protojson keys are lowerCamelCase: config.oauth2Config.clientId.
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
- config.oauth2Config.scopes 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/cce0a72d6dfd6119.
Report an issue: GitHub.