usememos/memos · error

notificationSetting must be populated for key NOTIFICATION

Error message

notificationSetting must be populated for key NOTIFICATION

What it means

Thrown when an instance-setting deployment file declares "key": "NOTIFICATION" but its notificationSetting payload message is nil. The notificationSetting carries the email/SMTP configuration; a NOTIFICATION file without it would configure nothing, so the loader fails at startup. Note the enum name: in the deployment JSON the key is written as "NOTIFICATION".

Source

Thrown at store/deployment_config.go:273

				{name: "accessKeyId", value: s3Config.AccessKeyId},
				{name: "accessKeySecret", value: s3Config.AccessKeySecret},
				{name: "endpoint", value: s3Config.Endpoint},
				{name: "region", value: s3Config.Region},
				{name: "bucket", value: s3Config.Bucket},
			} {
				if strings.TrimSpace(field.value) == "" {
					return errors.Errorf("storageSetting default S3 config.%s is required", field.name)
				}
			}
		}
	case storepb.InstanceSettingKey_MEMO_RELATED:
		if setting.GetMemoRelatedSetting() == nil {
			return errors.New("memoRelatedSetting must be populated for key MEMO_RELATED")
		}
	case storepb.InstanceSettingKey_NOTIFICATION:
		notification := setting.GetNotificationSetting()
		if notification == nil {
			return errors.New("notificationSetting must be populated for key NOTIFICATION")
		}
		if email := notification.Email; email != nil && email.Enabled {
			if strings.TrimSpace(email.SmtpHost) == "" || email.SmtpPort <= 0 || strings.TrimSpace(email.FromEmail) == "" {
				return errors.New("enabled notification email requires smtpHost, a positive smtpPort, and fromEmail")
			}
			if email.UseTls && email.UseSsl {
				return errors.New("notification email cannot enable both useTls and useSsl")
			}
		}
	case storepb.InstanceSettingKey_AI:
		if setting.GetAiSetting() == nil {
			return errors.New("aiSetting must be populated for key AI")
		}
		if err := normalizeDeploymentAISetting(setting.GetAiSetting()); err != nil {
			return err
		}
	case storepb.InstanceSettingKey_BASIC, storepb.InstanceSettingKey_TAGS:
		return errors.Errorf("key %s cannot be deployment configured", setting.Key)

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Add a "notificationSetting" object, e.g. { "key": "NOTIFICATION", "notificationSetting": { "email": { "enabled": true, ... } } }.
  2. Check the exact payload key notificationSetting.

Example fix

// before
{ "key": "NOTIFICATION" }

// after
{ "key": "NOTIFICATION", "notificationSetting": { "email": { "enabled": false } } }
Defensive patterns

Strategy: validation

Validate before calling

if setting.Key == storepb.InstanceSettingKey_NOTIFICATION && setting.GetNotificationSetting() == nil {
    return errors.New("NOTIFICATION setting requires a notificationSetting payload")
}

Type guard

func hasNotificationPayload(s *storepb.InstanceSetting) bool {
    return s.GetKey() == storepb.InstanceSettingKey_NOTIFICATION && s.GetNotificationSetting() != nil
}

Prevention

When it happens

Trigger: A memos-instance-setting-notification.json with only { "key": "NOTIFICATION" }, or a payload key typo like "notification_setting" leaving the oneof unset.

Common situations: Placeholder files created before SMTP details are known; converting an admin-API settings dump where the notification payload was nested differently.

Related errors


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