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

  1. Check write access and free space, then retry any AI editor action — migration is idempotent and will re-attempt the key removal
  2. Manually delete the "local-ai" key from data/storage/local.json with SiYuan closed if the retry keeps failing
  3. Verify local.json parses as valid JSON overall (corruption elsewhere in the file also breaks the write)
  4. 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

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


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/5b4352f6d55a2b8e. Report an issue: GitHub.