siyuan-note/siyuan · warning
remove legacy AI editor actions failed: %w
Error message
remove legacy AI editor actions failed: %w
What it means
Migration merged legacy actions and (if changed) saved actions.json successfully, but the final cleanup step failed: RemoveLocalStorageVals could not delete the "local-ai" key, which rewrites data/storage/local.json via setLocalStorage (marshal + filelock write). The merged data is already persisted; only the stale legacy key removal failed, so migration will retry on the next AI editor action call and dedup by (name, action) prevents duplicates.
Source
Thrown at kernel/model/ai_editor.go:262
}
data.Actions = append(data.Actions, &AIEditorAction{
ID: ast.NewNodeID(),
Name: legacyAction.Name,
Action: legacyAction.Memo,
})
existing[key] = struct{}{}
changed = true
}
if !persist {
return nil
}
if changed {
if err = saveAIEditorActions(data); err != nil {
return err
}
}
if err = RemoveLocalStorageVals([]string{legacyAIEditorActionsStorageKey}); err != nil {
return fmt.Errorf("remove legacy AI editor actions failed: %w", err)
}
return nil
}
View on GitHub (pinned to afa823b6b4)
Solutions
- Check write access and free space, then retry any AI editor action — migration is idempotent and will re-attempt the key removal
- Manually delete the "local-ai" key from data/storage/local.json with SiYuan closed if the retry keeps failing
- Verify local.json parses as valid JSON overall (corruption elsewhere in the file also breaks the write)
- Confirm data/storage/ai/editor/actions.json contains the migrated actions before discarding the legacy key
Example fix
// manual cleanup with SiYuan closed
// data/storage/local.json before: { "local-ai": "[...]", ... }
// delete the "local-ai" entry, save the file Defensive patterns
Strategy: retry
Validate before calling
// Ensure local.json is writable before actions that trigger migration
p := filepath.Join(util.DataDir, "storage", "local.json")
if f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE, 0644); err != nil {
return fmt.Errorf("local storage not writable: %w", err)
} else { f.Close() } Try / catch
if _, err := model.GetAIEditorActions(); err != nil {
if strings.Contains(err.Error(), "remove legacy AI editor actions failed") {
// data already migrated; retry once after fixing local.json writability — dedup makes it safe
}
} Prevention
- Keep data/storage writable by the kernel process
- Retry migration after transient lock/disk issues — it dedupes by (name, action)
- Delete the local-ai key manually only after verifying actions.json holds the merged actions
When it happens
Trigger: local.json on disk is read-only/locked, disk is full, or local.json contains other values that fail marshaling — any failure inside setLocalStorage while deleting local-ai.
Common situations: Filesystem permission changes after initial write, sync clients locking local.json, disk-full conditions appearing mid-migration, or another local-ai-adjacent corrupt entry making the whole map unmarshalable-to-write.
Related errors
- unmarshal legacy AI editor actions failed: %w
- marshal legacy AI editor actions failed: %w
- attribute view spec is too new
- marketplace package install path already exists
- install local marketplace package failed: %w; rollback faile
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/5b4352f6d55a2b8e.
Report an issue: GitHub.