{"record":{"id":"50cb2f634888ba19","repo":"siyuan-note/siyuan","slug":"path-and-content-required","errorCode":null,"errorMessage":"path and content required","messagePattern":"path and content required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_storage.go","lineNumber":235,"sourceCode":"\t\t})\n\t\tif runErr != nil {\n\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.get worker run: %v\", p.Name, runErr)\n\t\t\tif rejectErr := reject(rt.NewGoError(runErr)); rejectErr != nil {\n\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.get reject: %v\", p.Name, rejectErr)\n\t\t\t}\n\t\t}\n\n\t\treturn rt.ToValue(promise)\n\t})))\n\n\t// siyuan.storage.put(path, content) -> Promise<void>\n\tlo.Must0(storage.Set(\"put\", rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {\n\t\tpromise, resolve, reject := rt.NewPromise()\n\n\t\tvar argErr error\n\t\tvar path, content string\n\t\tif len(call.Arguments) < 2 {\n\t\t\targErr = fmt.Errorf(\"path and content required\")\n\t\t} else {\n\t\t\tpath = call.Argument(0).String()\n\t\t\tcontent = call.Argument(1).String()\n\t\t}\n\n\t\trunErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {\n\t\t\tif argErr != nil {\n\t\t\t\terr = argErr\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif util.ReadOnly {\n\t\t\t\terr = fmt.Errorf(\"The current kernel is in read-only mode, storage.put is not allowed\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tabs, resolveErr := resolvePath(path)\n\t\t\tif resolveErr != nil {\n\t\t\t\terr = resolveErr","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_storage.go#L217-L253","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nawait siyuan.storage.put(\"settings.json\", settings); // object, and counted as 1 usable call only if 2 args present; if omitted entirely:\nawait siyuan.storage.put(\"settings.json\"); // error: path and content required\n// after\nawait siyuan.storage.put(\"settings.json\", JSON.stringify(settings));","handlingStrategy":"validation","validationCode":"function assertPutArgs(path, content) { if (arguments.length < 2) throw new TypeError(\"storage.put requires path and content\"); }","typeGuard":"const canPut = (p, c) => typeof p === \"string\" && p.length > 0 && typeof c === \"string\";","tryCatchPattern":"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; }","preventionTips":["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"],"tags":["plugins","arguments","filesystem","siyuan"],"backgroundTag":"missing-required-argument","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}