siyuan-note/siyuan · error · Error
Failed to view state
Error message
Failed to ${action} view state What it means
checkResponse is the response gate for ViewStateService's default transport. When the kernel response for /api/storage/getViewState or /api/storage/patchViewState is missing or returns code !== 0, it throws either the server's msg or this generic `Failed to <action> view state` message. It converts transport-level failures into a uniform exception for get and patch.
Solutions
- Confirm the kernel is reachable and the workspace is open
- Inspect response.msg in the caught error for the kernel-side cause
- Reduce patch size (fewer values / removeKeys) if the request was too large
- Retry after connectivity is restored; view state patching is debounced so transient failures can be retried safely
Example fix
// before
await service.patch({fontSize: 14});
// after
try {
await service.patch({fontSize: 14});
} catch (e) {
if (e.message.includes("Failed to patch view state")) {
queueRetry(() => service.patch({fontSize: 14}));
}
} Defensive patterns
Strategy: retry
Validate before calling
// ensure kernel reachable before heavy state usage
const ping = await fetchPost("/api/system/version", {}); Try / catch
try { await checkResponseWork(); } catch (e) { if (e.message.startsWith("Failed to")) retryWithBackoff(); else throw e; } Prevention
- Check kernel connectivity before relying on view state persistence
- Keep patches under the 256KB / 1000-entry limits
- Debounce and retry transient transport failures
When it happens
Trigger: Calling ViewStateService.get or patch (via checkResponse, app/src/util/viewState.ts:44) when fetchSyncPost returns undefined/empty (network down, kernel unreachable) or the kernel rejects the request (storage API error, oversized patch beyond MAX_PATCH_BYTES, malformed key).
Common situations: Kernel not running or workspace closed; network failure on mobile/remote connections; storage record write rejected server-side; patch payload exceeding size limits.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Access to encrypted notebook data is not supported via this…
- agent context cannot be compacted enough: persist compaction
- AI editor action must not be empty
- AI editor action not found
- [/api/av/batchSetAttributeViewBlockAttrs] parameter [rowID]…
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/30ac364e7a4b967f.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/util/viewState.ts:44
const getPatchByteLength = (values: TViewStateData, removeKeys: string[]) => {
const json = JSON.stringify({values, removeKeys});
if (typeof json !== "string") {
throw new Error("Invalid view state patch");
}
const goCompatibleJSON = json.replace(/[<>&\u2028\u2029]/g, character => {
return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
});
return new TextEncoder().encode(goCompatibleJSON).byteLength;
};
const isViewStateData = (value: unknown): value is TViewStateData => {
return typeof value === "object" && value !== null && !Array.isArray(value);
};
const checkResponse = (response: IWebSocketData, action: string) => {
if (!response || response.code !== 0) {
throw new Error(response?.msg || `Failed to ${action} view state`);
}
};
const defaultTransport: IViewStateTransport = {
async get(key) {
const {fetchSyncPost} = await import("./fetch");
const response = await fetchSyncPost("/api/storage/getViewState", {key});
checkResponse(response, "get");
return isViewStateData(response.data) ? response.data : {};
},
async patch(key, values, removeKeys) {
const {fetchSyncPost} = await import("./fetch");
const response = await fetchSyncPost("/api/storage/patchViewState", {key, values, removeKeys});
checkResponse(response, "patch");
},
};
const validateIdentityPart = (name: string, value: string) => {View on GitHub (pinned to 9f775e8a12)