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

  1. Ensure the key is non-empty before calling — validate/derive a fallback key at the call site
  2. 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
  3. 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

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


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