siyuan-note/siyuan · error
AI editor action must not be empty
Error message
AI editor action must not be empty
What it means
SaveAIEditorAction validates that the supplied action carries at least a name or an action prompt. A nil pointer, or an object with both Name and Action empty, has nothing to persist and is rejected up-front.
Source
Thrown at kernel/model/ai_editor.go:72
func GetAIEditorActions() (ret []*AIEditorAction, err error) {
waitForSyncingStorages()
aiEditorActionsLock.Lock()
defer aiEditorActionsLock.Unlock()
data, err := loadAIEditorActions()
if err != nil {
return nil, err
}
if err = migrateLegacyAIEditorActions(data, !util.ReadOnly); err != nil {
return nil, err
}
return data.Actions, nil
}
func SaveAIEditorAction(action *AIEditorAction) (ret *AIEditorAction, err error) {
if action == nil || (action.Name == "" && action.Action == "") {
return nil, errors.New("AI editor action must not be empty")
}
if action.ID != "" && !ast.IsNodeIDPattern(action.ID) {
return nil, errors.New("invalid AI editor action ID")
}
waitForSyncingStorages()
aiEditorActionsLock.Lock()
defer aiEditorActionsLock.Unlock()
data, err := loadAIEditorActions()
if err != nil {
return nil, err
}
if err = migrateLegacyAIEditorActions(data, true); err != nil {
return nil, err
}
ret = &AIEditorAction{View on GitHub (pinned to 8641553a1f)
Solutions
- Ensure the request body includes a non-empty name or action prompt
- Return a validation error in the client before calling the API when both fields are blank
- Check the frontend form is binding inputs to the payload correctly
Example fix
// before
await fetchPost('/api/ai/saveAIEditorAction', {})
// after
await fetchPost('/api/ai/saveAIEditorAction', {name: 'Translate', action: 'Translate the selection to English'}) Defensive patterns
Strategy: validation
Validate before calling
if (!payload || (!payload.name && !payload.action)) { throw new Error('Name or action prompt is required') } Type guard
const isValidActionInput = (a) => a != null && (typeof a.name === 'string' && a.name.trim() !== '' || typeof a.action === 'string' && a.action.trim() !== '')
Try / catch
try { await saveAction(a) } catch (e) { if (e.message.includes('must not be empty')) showToast('Fill in name or prompt') } Prevention
- Validate the form before submitting
- Never post empty bodies to the save endpoint
- Require at least the action prompt in UI flows
When it happens
Trigger: Calling SaveAIEditorAction(nil) or SaveAIEditorAction(&AIEditorAction{}) (both fields empty) via the saveAIEditorAction API or tests.
Common situations: Frontend form submitted without filling fields; API call with an empty JSON body deserialized to a zero-value struct; client bug sending null payload.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- custom emoji file must not be empty
- no valid IDs provided
- empty HEIF image
- empty HEIF image
- AI editor input is empty
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/c8516b070ebbce4b.
Report an issue: GitHub.