siyuan-note/siyuan · error

Failed to save agent session

Error message

Failed to save agent session

What it means

Thrown by the agent SessionStore persist path when saving a session snapshot to the kernel fails after queued retries: the write returned an error or an expected-revision conflict could not be resolved, so the session was not durably stored.

Solutions

  1. Retry saving the session
  2. Reload the agent panel to resync session state from the server
  3. Check kernel storage availability and logs
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at app/src/layout/dock/agent/SessionStore.ts:187 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at app/src/layout/dock/agent/SessionStore.ts:187

        }
        // 连续写入期间若三次读取都落后于本地已知版本,则不返回旧数据覆盖界面。
        return null;
    },

    async save(session: AgentSession): Promise<SessionSaveResult> {
        const snapshot = JSON.parse(JSON.stringify(session)) as AgentSession;
        snapshot.updatedAt = Date.now();
        const baseRevision = snapshot.expectedRevision ?? sessionRevisions.get(snapshot.id) ?? snapshot.revision ?? 0;
        const previous = sessionSaveQueues.get(snapshot.id);
        const persist = async (expectedRevision: number) => {
            snapshot.expectedRevision = expectedRevision;
            const resp = await fetchSyncPost(API + "/saveSession", snapshot, APP_HEADER) as {
                code: number;
                msg?: string;
                data?: {revision?: number; session?: AgentSession};
            };
            if (!resp || resp.code !== 0) {
                throw new Error(resp?.msg || "Failed to save agent session");
            }
            const revision = resp.data?.revision ?? expectedRevision;
            sessionRevisions.set(snapshot.id, revision);
            if (snapshot.commitTurnID || snapshot.recoveryTurnID) {
                sessionRuntimeRevisions.set(snapshot.id, 0);
            }
            return {revision, session: resp.data?.session};
        };
        const save = previous ? previous.then((result) => persist(result.revision)) : persist(baseRevision);
        sessionSaveQueues.set(snapshot.id, save);
        try {
            return await save;
        } finally {
            if (sessionSaveQueues.get(snapshot.id) === save) {
                sessionSaveQueues.delete(snapshot.id);
            }
        }
    },

View on GitHub (pinned to 9f775e8a12)