siyuan-note/siyuan · error

invalid view state data key

Error message

invalid view state data key

What it means

validateViewStateDataKey rejects a view-state data key that is empty/whitespace-only or longer than 2048 bytes. The kernel stores per-view state payloads keyed by data keys, and keys beyond these limits would bloat or break the storage format, so PatchViewState refuses the write before persisting anything.

Source

Thrown at kernel/model/view_state.go:220

			return int64(len(keys) + 1)
		}
		if ret <= state.Updated {
			ret = state.Updated + 1
		}
	}
	return ret
}

func validateViewStateKey(key string) error {
	if "" == strings.TrimSpace(key) || 1024 < len(key) {
		return errors.New("invalid view state key")
	}
	return nil
}

func validateViewStateDataKey(key string) error {
	if "" == strings.TrimSpace(key) || 2048 < len(key) {
		return errors.New("invalid view state data key")
	}
	return nil
}

func pruneViewStates(views map[string]*ViewState) {
	if len(views) <= maxViewStateCount {
		return
	}

	keys := make([]string, 0, len(views))
	for key := range views {
		keys = append(keys, key)
	}
	sort.Slice(keys, func(i, j int) bool {
		left, right := views[keys[i]], views[keys[j]]
		if left.Updated == right.Updated {
			return keys[i] < keys[j]
		}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Ensure the data key is non-empty and trimmed before calling the patch API.
  2. Shorten the key: hash long identifiers (e.g. SHA-256 hex) instead of embedding full paths/URLs, keeping it under 2048 characters.
  3. Log the failing key at the call site to identify which concatenation produced an empty or oversized value.

Example fix

// before
const key = `${docPath}/${blockId}/${extra}`;
await patchViewState(viewId, key, data);

// after
const key = [docPath, blockId, extra].filter(Boolean).join("/").slice(0, 2048);
if (!key.trim()) throw new Error("view state data key required");
await patchViewState(viewId, key, data);
Defensive patterns

Strategy: validation

Validate before calling

function isValidViewStateDataKey(key) {
  return typeof key === "string" && key.trim().length > 0 && key.length <= 2048;
}
if (!isValidViewStateDataKey(key)) throw new Error("refusing to patch view state: bad data key");

Type guard

const isViewStateDataKey = (v) => typeof v === "string" && v.trim() !== "" && v.length <= 2048;

Prevention

When it happens

Trigger: Calling the view-state patch API (PatchViewState path) with a data key that is "" or all whitespace, or a string whose length exceeds 2048 characters.

Common situations: A plugin or frontend feature builds the data key by concatenating IDs/paths and accidentally produces an empty string when an ID is missing; or embeds a long document path/blob ID, URL, or serialized JSON that exceeds 2048 characters.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/d6a34e9686f2f49f. Report an issue: GitHub.