siyuan-note/siyuan · error

local storage value for key

Error message

local storage value for key [%s] must not be empty

What it means

SetLocalStorageVals validates every key/value pair before persisting to the kernel's local storage (localStorage.json in the workspace). If any value in the submitted map is nil, the whole operation aborts with this error and nothing is written, since a nil value would corrupt the stored JSON map semantics. It is a client-input validation guard on the /api/storage/setLocalStorageVals endpoint.

Solutions

  1. Inspect the keyVals payload and remove or replace every null value with a concrete value before calling the API
  2. On the caller side, filter entries: build the map only from keys whose value is non-nil/non-undefined
  3. If the key should be cleared, use the remove-local-storage API/omit the key instead of passing nil

Example fix

// before
fetchPost("/api/storage/setLocalStorageVals", {keyVals: {theme: undefinedVal}})
// after
if (undefinedVal != null) {
  fetchPost("/api/storage/setLocalStorageVals", {keyVals: {theme: undefinedVal}})
}
Defensive patterns

Strategy: validation

Validate before calling

function canSetLocalStorageVals(keyVals) {
  return Object.entries(keyVals).every(([k, v]) => v != null);
}
if (!canSetLocalStorageVals(keyVals)) throw new Error("null value in keyVals");

Type guard

function hasNoNilValues(m map[string]any) bool {
  for _, v := range m { if v == nil { return false } }
  return true
}

Prevention

When it happens

Trigger: Calling kernel API /api/storage/setLocalStorageVals with a JSON payload where some key maps to null; frontend/plugin code doing localStorage setItem with an undefined-valued variable.

Common situations: A frontend reads an unset variable (undefined) and serializes it to null; a plugin builds the keyVals map programmatically and one optional field is missing; deserialized data lost a value.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/84a1a0b65752fdbe. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/storage.go:61

	defer localStorageLock.Unlock()
	return getLocalStorage()
}

func SetLocalStorage(val map[string]any) (err error) {
	localStorageLock.Lock()
	defer localStorageLock.Unlock()
	return setLocalStorage(val)
}

func SetLocalStorageVals(keyVals map[string]any) (setKeyVals map[string]any, err error) {
	localStorageLock.Lock()
	defer localStorageLock.Unlock()

	setKeyVals = make(map[string]any, len(keyVals))
	localStorage := getLocalStorage()
	for k, v := range keyVals {
		if v == nil {
			err = fmt.Errorf("local storage value for key [%s] must not be empty", k)
			return
		}
		localStorage[k] = v
		setKeyVals[k] = v
	}
	err = setLocalStorage(localStorage)
	return
}

func RemoveLocalStorageVals(keys []string) (err error) {
	localStorageLock.Lock()
	defer localStorageLock.Unlock()

	localStorage := getLocalStorage()
	for _, key := range keys {
		delete(localStorage, key)
	}
	return setLocalStorage(localStorage)

View on GitHub (pinned to 9f775e8a12)