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

  1. Pass exactly two string arguments: await siyuan.storage.put("data.json", JSON.stringify(obj))
  2. Check arguments.length >= 2 or validate both values before calling
  3. 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

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


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 = resolveErr

View on GitHub (pinned to 9f775e8a12)