usememos/memos · error

aiSetting must be populated for key AI

Error message

aiSetting must be populated for key AI

What it means

Thrown when an instance-setting deployment file declares "key": "AI" but its aiSetting payload message is nil. The aiSetting must be present and is then passed to normalizeDeploymentAISetting for deeper validation (provider references, transcription limits). A key without payload is rejected at startup as an invalid instance setting deployment file.

Source

Thrown at store/deployment_config.go:285

		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)
	default:
		return errors.Errorf("unsupported instance setting key %s", setting.Key)
	}
	return nil
}

func normalizeDeploymentAISetting(setting *storepb.InstanceAISetting) error {
	providers := map[string]struct{}{}
	for i, provider := range setting.Providers {
		if provider == nil {
			return errors.Errorf("aiSetting.providers[%d] must not be null", i)
		}

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Add an "aiSetting" object, e.g. { "key": "AI", "aiSetting": { "providers": [ ... ] } }.
  2. Check the payload key is exactly aiSetting.

Example fix

// before
{ "key": "AI" }

// after
{ "key": "AI", "aiSetting": { "providers": [ { "id": "openai", "name": "OpenAI", "type": "OPENAI", "apiKey": "sk-..." } ] } }
Defensive patterns

Strategy: validation

Validate before calling

if setting.Key == storepb.InstanceSettingKey_AI && setting.GetAiSetting() == nil {
    return errors.New("AI setting requires an aiSetting payload")
}

Type guard

func hasAiPayload(s *storepb.InstanceSetting) bool {
    return s.GetKey() == storepb.InstanceSettingKey_AI && s.GetAiSetting() != nil
}

Prevention

When it happens

Trigger: A memos-instance-setting-ai.json with only { "key": "AI" } or a mistyped payload key ("ai_setting", "ai") that protojson ignores.

Common situations: Placeholder AI file created before API keys are provisioned; secret-mounting that renders an empty payload object.

Related errors


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