siyuan-note/siyuan · error
panic during siyuan.storage.list
Error message
panic during siyuan.storage.list: %v
What it means
The background goroutine that lists the directory for siyuan.storage.list has a deferred recover(); any panic during the listing or the Promise resolve/reject bridge is converted to this error and rejects the Promise. It indicates an unexpected internal crash rather than a caller-visible filesystem problem.
Solutions
- Check kernel logs for the panic context and report with the plugin name
- Await all storage Promises before unloading/disabling the plugin
- Retry the list operation once
- Update the kernel and plugin to latest versions
Defensive patterns
Strategy: try-catch
Try / catch
try {
const entries = await siyuan.storage.list(dir);
} catch (e) {
if (String(e).includes("panic during")) {
console.error("kernel-internal panic during list; check kernel logs");
} else throw e;
} Prevention
- Await pending storage Promises before plugin unload
- Avoid concurrent storage calls racing shutdown
- Keep kernel and plugins updated
When it happens
Trigger: A runtime panic inside the storage.list goroutine, e.g. while building the result array or while re-entering the goja worker to resolve the Promise. Rare and typically kernel-internal.
Common situations: Plugin/worker being torn down concurrently with an in-flight list; goja runtime bridge faults; kernel bugs.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- panic during siyuan.storage.remove
- injectAgent
- injectClient
- injectStorage
- panic during lifecycle hook invocation
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/9b0f5322ae480126.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_storage.go:409
} else {
path = call.Argument(0).String()
}
runErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {
if argErr != nil {
err = argErr
return
}
abs, resolveErr := resolvePath(path)
if resolveErr != nil {
err = resolveErr
return
}
go func() (result any, err error) {
defer func() {
if r := recover(); r != nil {
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)View on GitHub (pinned to 9f775e8a12)