siyuan-note/siyuan · error
path and content required
Error message
path and content required
What it means
Thrown as a rejected Promise when siyuan.storage.put(path, content) is called with fewer than two arguments. Both the storage-relative path and the string content must be supplied positionally; calling put with only a path (or nothing) fails this guard before the read-only check or path resolution.
Solutions
- Pass exactly two string arguments: await siyuan.storage.put("data.json", JSON.stringify(obj))
- Check arguments.length >= 2 or validate both values before calling
- Stringify objects explicitly — put does not accept objects as content
Example fix
// before
await siyuan.storage.put("settings.json", settings); // object, and counted as 1 usable call only if 2 args present; if omitted entirely:
await siyuan.storage.put("settings.json"); // error: path and content required
// after
await siyuan.storage.put("settings.json", JSON.stringify(settings)); Defensive patterns
Strategy: validation
Validate before calling
function assertPutArgs(path, content) { if (arguments.length < 2) throw new TypeError("storage.put requires path and content"); } Type guard
const canPut = (p, c) => typeof p === "string" && p.length > 0 && typeof c === "string";
Try / catch
try { await siyuan.storage.put(path, content); } catch (e) { if (e.message.includes("path and content required")) console.error("put called with missing args"); else throw e; } Prevention
- Always pass exactly two string arguments; JSON.stringify objects yourself
- Wrap siyuan.storage.put in a typed helper that enforces both parameters
- Avoid spreading option objects into put — it takes positional arguments only
When it happens
Trigger: Calling siyuan.storage.put("file.json") with the content omitted; spreading an options object instead of passing two arguments; a code path where the content variable is conditionally undefined and the call still executes.
Common situations: Plugin authors porting from key/value storage APIs that take a single object; forgetting JSON.stringify when intending to store an object; refactors that drop the second argument.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- failed to make directory
- failed to remove storage path from watcher
- failed to write file
- panic during siyuan.storage.get
- panic during siyuan.storage.put
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/50cb2f634888ba19.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_storage.go:235
})
if runErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.get worker run: %v", p.Name, runErr)
if rejectErr := reject(rt.NewGoError(runErr)); rejectErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.storage.get reject: %v", p.Name, rejectErr)
}
}
return rt.ToValue(promise)
})))
// siyuan.storage.put(path, content) -> Promise<void>
lo.Must0(storage.Set("put", rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
promise, resolve, reject := rt.NewPromise()
var argErr error
var path, content string
if len(call.Arguments) < 2 {
argErr = fmt.Errorf("path and content required")
} else {
path = call.Argument(0).String()
content = call.Argument(1).String()
}
runErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {
if argErr != nil {
err = argErr
return
}
if util.ReadOnly {
err = fmt.Errorf("The current kernel is in read-only mode, storage.put is not allowed")
return
}
abs, resolveErr := resolvePath(path)
if resolveErr != nil {
err = resolveErrView on GitHub (pinned to 9f775e8a12)