siyuan-note/siyuan · error
path and content required
Error message
path and content required
What it means
Thrown by siyuan.storage.put() when fewer than two arguments are supplied. put writes content to a file under the plugin storage dir and requires both a path and a content string. The check is purely on argument count (len < 2), so omitting either the path or the content triggers it; note it does not additionally verify the types.
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 251596fc0d)
Solutions
- Always pass both arguments: put(path, content).
- Default content to an empty string when you intentionally want to truncate.
- Validate that the content variable is defined before calling put.
Example fix
// before
await siyuan.storage.put('state.json');
// after
await siyuan.storage.put('state.json', JSON.stringify(state)); Defensive patterns
Strategy: validation
Validate before calling
if (arguments.length < 2 || typeof path !== 'string') {
throw new TypeError('storage.put requires (path: string, content: string)');
} Type guard
const isPutArgs = (p, c) => typeof p === 'string' && typeof c === 'string';
Try / catch
try { await siyuan.storage.put(path, content); }
catch (e) { if (/path and content required/.test(String(e))) { /* missing arg */ } else throw e; } Prevention
- Default content to '' when intentionally truncating.
- Serialize objects with JSON.stringify before passing as content.
When it happens
Trigger: Calling storage.put('x') with only a path and no content; put() with no arguments; put(undefined, undefined).
Common situations: Plugin builds the content lazily and forgets to pass it when empty; serialization step that produced undefined content was skipped; refactor changed put signatures and a call site was missed.
Related errors
- path required
- method name required
- method required
- siyuan.storage: path traversal not allowed
- failed to add storage path to watcher: %v
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/50cb2f634888ba19.
Report an issue: GitHub.