siyuan-note/siyuan · error
failed to remove
Error message
failed to remove: %w
What it means
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>'.
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
Example fix
// before
await siyuan.storage.remove(file);
// after
try {
await siyuan.storage.remove(file);
} catch (e) {
console.error("remove failed:", String(e)); // inspect wrapped OS cause
} Defensive patterns
Strategy: try-catch
Try / catch
try {
await siyuan.storage.remove(path);
} catch (e) {
const cause = String(e); // 'failed to remove: <os error>'
if (cause.includes("permission denied") || cause.includes("resource temporarily unavailable")) {
// retry after delay or notify user
} else throw e;
} Prevention
- Close file handles before deleting
- Retry transient lock errors with backoff
- Verify permissions on the plugin storage directory
When it happens
Trigger: 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.
Common situations: Files opened by another application on Windows; read-only file attributes; permission changes on the storage directory; antivirus holding files briefly.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- failed to read directory
- The current kernel is in read-only mode, storage.remove is…
- attribute view definition is not a regular file
- cannot remove storage root
- failed to add storage path to watcher
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/7998b10946f5bb1f.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_storage.go:359
err = fmt.Errorf("panic during siyuan.storage.remove: %v", r)
}
p.worker.Run(func(rt *goja.Runtime) (_ any, _ error) {
if lo.IsNil(err) {
if resolveErr := resolve(result); resolveErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.remove resolve: %v", p.Name, resolveErr)
}
} else {
if rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.remove reject: %v", p.Name, rejectErr)
}
}
return
}, nil)
}()
if removeErr := os.RemoveAll(abs); removeErr != nil {
err = fmt.Errorf("failed to remove: %w", removeErr)
return
}
return
}()
return
}, func(rt *goja.Runtime, result any, err error) {
if !lo.IsNil(err) {
if rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.remove reject: %v", p.Name, rejectErr)
}
}
})
if runErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.remove worker run: %v", p.Name, runErr)
if rejectErr := reject(rt.NewGoError(runErr)); rejectErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.remove reject: %v", p.Name, rejectErr)
}View on GitHub (pinned to 9f775e8a12)