siyuan-note/siyuan · error
AI editor action not found
Error message
AI editor action not found
What it means
SaveAIEditorAction performs an update when the action has an ID: it searches the stored action list for a matching ID and replaces it. If no stored action has that ID, the update target is missing and this error is returned instead of silently creating a duplicate.
Source
Thrown at kernel/model/ai_editor.go:108
ret = &AIEditorAction{
ID: action.ID,
Name: action.Name,
Action: action.Action,
}
if ret.ID == "" {
ret.ID = ast.NewNodeID()
data.Actions = append(data.Actions, ret)
} else {
updated := false
for i, item := range data.Actions {
if item.ID == ret.ID {
data.Actions[i] = ret
updated = true
break
}
}
if !updated {
return nil, errors.New("AI editor action not found")
}
}
if err = saveAIEditorActions(data); err != nil {
return nil, err
}
return ret, nil
}
func RemoveAIEditorAction(id string) (err error) {
if !ast.IsNodeIDPattern(id) {
return errors.New("invalid AI editor action ID")
}
waitForSyncingStorages()
aiEditorActionsLock.Lock()
defer aiEditorActionsLock.Unlock()
View on GitHub (pinned to 8641553a1f)
Solutions
- Re-fetch the current action list (getAIEditorActions) and retry with a live ID
- If the action was intentionally new, omit the ID to create it instead of updating
- Confirm the kernel is running against the workspace that contains the action
Example fix
// before
await fetchPost('/api/ai/saveAIEditorAction', {id: staleID, name: 'X', action: 'Y'})
// after
const {data} = await fetchPost('/api/ai/getAIEditorActions', {})
if (data.actions.some(a => a.id === staleID)) {
await fetchPost('/api/ai/saveAIEditorAction', {id: staleID, name: 'X', action: 'Y'})
} Defensive patterns
Strategy: try-catch
Validate before calling
const exists = (await fetchPost('/api/ai/getAIEditorActions', {})).data.actions.some(a => a.id === id); if (!exists) { /* create without id instead */ } Try / catch
try { await saveAction({id, ...}) } catch (e) { if (e.message === 'AI editor action not found') { await refreshActions(); /* recreate or surface conflict */ } } Prevention
- Refresh the action list before updates in multi-session setups
- Handle deletion races by falling back to create
- Avoid holding stale IDs across workspace switches
When it happens
Trigger: Calling SaveAIEditorAction with an ID that is syntactically valid but does not exist in the persisted actions list (action deleted elsewhere, stale client cache, wrong workspace).
Common situations: Two clients/sessions where one deleted the action; client retrying an update after the action was removed; pointing the kernel at a different workspace than the one holding the action.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Content block with id [%s] not found
- attribute view not found
- view not found
- key not found
- item not found
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/b075aa5c8a7c0dac.
Report an issue: GitHub.