{"record":{"id":"5b4352f6d55a2b8e","repo":"siyuan-note/siyuan","slug":"remove-legacy-ai-editor-actions-failed-w","errorCode":null,"errorMessage":"remove legacy AI editor actions failed: %w","messagePattern":"remove legacy AI editor actions failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/ai_editor.go","lineNumber":262,"sourceCode":"\t\t}\n\t\tdata.Actions = append(data.Actions, &AIEditorAction{\n\t\t\tID:     ast.NewNodeID(),\n\t\t\tName:   legacyAction.Name,\n\t\t\tAction: legacyAction.Memo,\n\t\t})\n\t\texisting[key] = struct{}{}\n\t\tchanged = true\n\t}\n\tif !persist {\n\t\treturn nil\n\t}\n\tif changed {\n\t\tif err = saveAIEditorActions(data); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err = RemoveLocalStorageVals([]string{legacyAIEditorActionsStorageKey}); err != nil {\n\t\treturn fmt.Errorf(\"remove legacy AI editor actions failed: %w\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":244,"sourceCodeEnd":266,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/ai_editor.go#L244-L266","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// manual cleanup with SiYuan closed\n// data/storage/local.json before: { \"local-ai\": \"[...]\", ... }\n// delete the \"local-ai\" entry, save the file","handlingStrategy":"retry","validationCode":"// Ensure local.json is writable before actions that trigger migration\np := filepath.Join(util.DataDir, \"storage\", \"local.json\")\nif f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE, 0644); err != nil {\n    return fmt.Errorf(\"local storage not writable: %w\", err)\n} else { f.Close() }","typeGuard":null,"tryCatchPattern":"if _, err := model.GetAIEditorActions(); err != nil {\n    if strings.Contains(err.Error(), \"remove legacy AI editor actions failed\") {\n        // data already migrated; retry once after fixing local.json writability — dedup makes it safe\n    }\n}","preventionTips":["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"],"tags":["migration","local-storage","filesystem","cleanup","go"],"backgroundTag":"file-write-permission-denied","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}