siyuan-note/siyuan · error
panic during siyuan.storage.get
Error message
panic during siyuan.storage.get: %v
What it means
The goroutine that performs the file read for siyuan.storage.get(path) recovered from a Go panic; the panic value is formatted into this message and the Promise is rejected. This is a defensive wrapper around unexpected internal failures during the read or result-marshalling phase, not a normal I/O error (those surface as their own messages).
Solutions
- Catch the rejection and inspect the embedded panic value for the concrete cause
- Retry the siyuan.storage.get call once — transient races between write and read often resolve
- Ensure the file is not being modified/deleted concurrently by your own plugin (serialize put/get)
- Report persistent occurrences with the panic text to the SiYuan kernel maintainers
Example fix
// before
const data = await siyuan.storage.get("state.json");
// after
let data;
try {
data = await siyuan.storage.get("state.json");
} catch (e) {
console.error("storage.get panicked:", e.message); // inspect wrapped panic
data = null; // fall back to defaults
} Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof path !== "string") throw new TypeError("path must be a string"); // avoids unrelated failure modes first Type guard
null
Try / catch
try { const data = await siyuan.storage.get(path); } catch (e) { console.error("storage.get panic:", e.message); return cachedDefaults; } Prevention
- Serialize put/get on the same file within your plugin to avoid read/write races
- Retry once on transient failures before surfacing the error
- Keep plugin data files modest in size and avoid deleting files mid-read
- Report persistent panics with the embedded value to SiYuan maintainers
When it happens
Trigger: A panic inside the deferred recovery path itself, in filelock.ReadFile, or while building the result object (ObjectSetDataMethods) for the get call; nil pointer or index-out-of-range bugs in the storage layer triggered by unusual file states.
Common situations: Kernel-side bugs or race conditions while reading a file concurrently being replaced; extremely large or unusual files stressing the marshalling path; running a plugin against a kernel build with an internal defect.
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.put
- failed to make directory
- failed to remove storage path from watcher
- failed to write file
- path and content required
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/68155adf601b8faa.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_storage.go:174
} else {
argErr = fmt.Errorf("path required")
}
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 []byte, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic during siyuan.storage.get: %v", r)
}
p.worker.Run(func(rt *goja.Runtime) (_ any, _ error) {
if err != nil {
return nil, err
}
content := rt.NewObject()
if err = ObjectSetDataMethods(p, rt, content, result); err != nil {
return nil, err
}
return content, nil
}, func(rt *goja.Runtime, result any, err error) {
if lo.IsNil(err) {
if resolveErr := resolve(result); resolveErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.get resolve: %v", p.Name, resolveErr)
}
} else {View on GitHub (pinned to 9f775e8a12)