{"record":{"id":"7998b10946f5bb1f","repo":"siyuan-note/siyuan","slug":"failed-to-remove-w","errorCode":null,"errorMessage":"failed to remove: %w","messagePattern":"failed to remove: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_storage.go","lineNumber":359,"sourceCode":"\t\t\t\t\t\terr = fmt.Errorf(\"panic during siyuan.storage.remove: %v\", r)\n\t\t\t\t\t}\n\n\t\t\t\t\tp.worker.Run(func(rt *goja.Runtime) (_ any, _ error) {\n\t\t\t\t\t\tif lo.IsNil(err) {\n\t\t\t\t\t\t\tif resolveErr := resolve(result); resolveErr != nil {\n\t\t\t\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.remove resolve: %v\", p.Name, resolveErr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {\n\t\t\t\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.remove reject: %v\", p.Name, rejectErr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}, nil)\n\t\t\t\t}()\n\n\t\t\t\tif removeErr := os.RemoveAll(abs); removeErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"failed to remove: %w\", removeErr)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}()\n\n\t\t\treturn\n\t\t}, func(rt *goja.Runtime, result any, err error) {\n\t\t\tif !lo.IsNil(err) {\n\t\t\t\tif rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {\n\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.remove reject: %v\", p.Name, rejectErr)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\tif runErr != nil {\n\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.remove worker run: %v\", p.Name, runErr)\n\t\t\tif rejectErr := reject(rt.NewGoError(runErr)); rejectErr != nil {\n\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.remove reject: %v\", p.Name, rejectErr)\n\t\t\t}","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_storage.go#L341-L377","documentation":"os.RemoveAll failed while deleting the resolved path for siyuan.storage.remove. The underlying OS error (permissions, file in use, nonexistent path on some platforms, etc.) is wrapped with %w and the Promise is rejected with 'failed to remove: <cause>'.","triggerScenarios":"Calling siyuan.storage.remove(path) where the OS cannot delete the target: insufficient permissions, the file/directory is locked by another process, or a nested entry cannot be removed so RemoveAll aborts.","commonSituations":"Files opened by another application on Windows; read-only file attributes; permission changes on the storage directory; antivirus holding files briefly.","solutions":["Read the wrapped cause to identify the OS error (EACCES/EBUSY/ENOENT)","Ensure the calling plugin has the necessary storage permissions and the target is not open elsewhere","Retry after a short delay if a lock/AV scanner held the file","Close file handles the plugin itself holds before removing"],"exampleFix":"// before\nawait siyuan.storage.remove(file);\n\n// after\ntry {\n  await siyuan.storage.remove(file);\n} catch (e) {\n  console.error(\"remove failed:\", String(e)); // inspect wrapped OS cause\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await siyuan.storage.remove(path);\n} catch (e) {\n  const cause = String(e); // 'failed to remove: <os error>'\n  if (cause.includes(\"permission denied\") || cause.includes(\"resource temporarily unavailable\")) {\n    // retry after delay or notify user\n  } else throw e;\n}","preventionTips":["Close file handles before deleting","Retry transient lock errors with backoff","Verify permissions on the plugin storage directory"],"tags":["plugin","storage","filesystem","os-error"],"backgroundTag":"file-write-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}