usememos/memos · error
config.oauth2Config.fieldMapping.identifier is required
Error message
config.oauth2Config.fieldMapping.identifier is required
What it means
Thrown when config.oauth2Config in a memos-idp-*.json file has no fieldMapping message or its identifier field is blank after trimming. The fieldMapping.identifier tells Memos which userinfo JSON property (e.g. "login", "email", "sub") identifies the user; without it the OAuth2 exchange cannot map a login to a Memos account, so the deployment file is rejected at startup.
Source
Thrown at store/deployment_config.go:217
{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")
}
if offset := setting.GetGeneralSetting().WeekStartDayOffset; offset < -1 || offset > 6 {
return errors.New("generalSetting.weekStartDayOffset must be between -1 and 6")
}
case storepb.InstanceSettingKey_STORAGE:
storage := setting.GetStorageSetting()
if storage == nil {
return errors.New("storageSetting must be populated for key STORAGE")
}View on GitHub (pinned to 14d757ce1f)
Solutions
- Add "fieldMapping": { "identifier": "<userinfo-key>" } under config.oauth2Config.
- For GitHub use "login"; for OIDC-compliant providers use "sub" or "email" depending on the userinfo payload.
Example fix
// before
"oauth2Config": { ..., "scopes": ["read:user"] }
// after
"oauth2Config": { ..., "scopes": ["read:user"], "fieldMapping": { "identifier": "login" } } Defensive patterns
Strategy: validation
Validate before calling
fm := cfg.GetFieldMapping()
if fm == nil || strings.TrimSpace(fm.Identifier) == "" {
return errors.New("config.oauth2Config.fieldMapping.identifier is required")
} Type guard
func hasIdentifierMapping(cfg *storepb.OAuth2Config) bool {
fm := cfg.GetFieldMapping()
return fm != nil && strings.TrimSpace(fm.GetIdentifier()) != ""
} Prevention
- Inspect the provider's userinfo endpoint response once (curl with a token) and map identifier to a key that is always present, e.g. "sub" or "login".
- Prefer stable identifiers (sub) over emails, which can change.
When it happens
Trigger: config.oauth2Config with "fieldMapping": {}, a missing "fieldMapping" key, or "identifier": "" / " ".
Common situations: Not knowing which userinfo attribute the provider returns (e.g. GitHub uses "login", generic OIDC uses "sub" or "email"); trimming the JSON down for testing and removing fieldMapping.
Related errors
- config.oauth2Config is required
- config.oauth2Config.scopes 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/fea0019b1e5a61e5.
Report an issue: GitHub.