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
- Add an "aiSetting" object, e.g. { "key": "AI", "aiSetting": { "providers": [ ... ] } }.
- 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
- Ship the AI file only when providers with API keys are ready to mount.
- Keep the payload key exactly aiSetting.
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
- generalSetting must be populated for key GENERAL
- generalSetting.weekStartDayOffset must be between -1 and 6
- storageSetting must be populated for key STORAGE
- memoRelatedSetting must be populated for key MEMO_RELATED
- notificationSetting must be populated for key NOTIFICATION
AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15).
Data as JSON: /api/errors/2ade46242ff20b4d.
Report an issue: GitHub.