siyuan-note/siyuan · error
failed to read directory
Error message
failed to read directory: %w
What it means
os.ReadDir failed for the resolved path in siyuan.storage.list. The OS error is wrapped and the Promise is rejected with 'failed to read directory: <cause>'. Common causes are the path not existing or not being a directory (ENOENT, ENOTDIR) or lacking read permission.
Solutions
- Create the directory first (e.g. write a file with siyuan.storage.put) or treat ENOENT as an empty result
- Ensure the path is a directory, not a file
- Check the wrapped OS error to distinguish not-found from permission problems
- Wrap the call in try/catch and fall back to an empty list for optional directories
Example fix
// before
const entries = await siyuan.storage.list(dir);
// after
let entries = [];
try {
entries = await siyuan.storage.list(dir);
} catch (e) {
if (!String(e).includes("no such file")) throw e;
} Defensive patterns
Strategy: fallback
Try / catch
let entries = [];
try {
entries = await siyuan.storage.list(dir);
} catch (e) {
if (String(e).includes("no such file")) {
entries = []; // treat missing dir as empty
} else throw e;
} Prevention
- Create the directory (via storage.put) before listing it
- Only pass directory paths to storage.list, never file paths
- Treat missing directories as empty results in optional-data flows
When it happens
Trigger: Calling siyuan.storage.list(path) where path was never created (e.g. before the first storage.put), points to a file instead of a directory, or the directory cannot be read due to permissions.
Common situations: Listing a subdirectory before any file was written into it; a typo in the path; assuming list works on file paths; directories deleted externally by sync or the user.
Related errors
- failed to remove
- The current kernel is in read-only mode, storage.remove is…
- attribute view definition is not a regular file
- cannot remove storage root
- create import dir failed
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/bf7e1f0b6654bef1.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_storage.go:427
err = fmt.Errorf("panic during siyuan.storage.list: %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.list resolve: %v", p.Name, resolveErr)
}
} else {
if rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.list reject: %v", p.Name, rejectErr)
}
}
return
}, nil)
}()
entries, readErr := os.ReadDir(abs)
if readErr != nil {
err = fmt.Errorf("failed to read directory: %w", readErr)
return
}
results := make([]R, 0, len(entries))
for _, entry := range entries {
info, infoErr := entry.Info()
if infoErr != nil {
continue
}
results = append(results, R{
"name": entry.Name(),
"isDir": info.IsDir(),
"isSymlink": util.IsSymlink(entry),
"updated": info.ModTime().Unix(),
})
}
result = resultsView on GitHub (pinned to 9f775e8a12)