siyuan-note/siyuan · error
invalid view state key
Error message
invalid view state key
What it means
validateViewStateKey requires a view-state key to be non-blank and at most 1024 bytes. Keys that are empty, whitespace-only, or longer than 1024 characters make GetViewState, PatchViewState, and RemoveViewState fail with this error.
Source
Thrown at kernel/model/view_state.go:213
return keys[i] < keys[j]
}
return left.Updated < right.Updated
})
for i, key := range keys {
views[key].Updated = int64(i + 1)
}
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 {View on GitHub (pinned to 8641553a1f)
Solutions
- Ensure the key is non-empty before calling — validate/derive a fallback key at the call site
- Shorten the key: use a fixed short namespace plus a hash (e.g. SHA-256 hex, 64 chars) of the long composite instead of the raw concatenation
- Check the frontend/API layer so an empty or whitespace key is rejected or defaulted before the request is sent
Example fix
// before key := docID + "/" + blockID + "/" + longContext model.PatchViewState(key, values, nil) // after sum := sha256.Sum256([]byte(docID + "/" + blockID + "/" + longContext)) key := "ctx-" + hex.EncodeToString(sum[:]) model.PatchViewState(key, values, nil)
Defensive patterns
Strategy: validation
Validate before calling
func isValidViewStateKey(key string) bool {
trimmed := strings.TrimSpace(key)
return trimmed != "" && len(key) <= 1024
} Type guard
func validViewStateKey(key string) (string, bool) {
if key == "" || strings.TrimSpace(key) == "" || len(key) > 1024 {
return "", false
}
return key, true
} Try / catch
if _, err := model.GetViewState(key); err != nil {
if strings.Contains(err.Error(), "invalid view state key") {
key = deriveViewStateKey(fallbackComponents) // short hashed key
_, err = model.GetViewState(key)
}
return err
}
return nil Prevention
- Reject empty/whitespace keys at the UI or API boundary before they reach view state
- Keep composite keys short — hash long components instead of concatenating raw IDs, paths, or URLs
- Test key construction with worst-case component lengths to confirm the result stays under 1024 bytes
When it happens
Trigger: GetViewState(key), PatchViewState(key, ...), or RemoveViewState(key) called with key == "", a whitespace-only string (e.g. " "), or a string longer than 1024 bytes (e.g. a concatenated document ID + block ID + plugin name that grew too long).
Common situations: An unset variable or empty request parameter reaching the API before validation; building keys from optional components where all components are missing; prefix-style keys that embed long paths, URLs, or IDs and exceed the length cap.
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
- view state patch contains too many entries
- view state patch is too large
- wrong layout type
- filter nesting depth exceeds the maximum allowed
- The top-level notebook document cannot be removed or moved
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/fa6238da426ac78d.
Report an issue: GitHub.