siyuan-note/siyuan · error

Failed to remove agent session

Error message

Failed to remove agent session

What it means

SessionStore.remove() calls the kernel endpoint /api/agent/removeSession and requires an API envelope with code===0. If the POST returns nothing or a non-zero code, it throws with the kernel-provided msg, or this fallback message when msg is absent. Local revision maps are only cleaned up after a successful removal.

Solutions

  1. Refresh the session list and retry removal on a session that still exists
  2. Inspect the kernel logs for the removeSession failure cause
  3. Check network/API availability (fetchSyncPost returning undefined indicates a failed request)
  4. If the session is already gone server-side, treat removal as done and clear local state

Example fix

// before
await store.remove(id); // throws if server session missing
// after
try { await store.remove(id); } catch (e) { sessionList.refresh(); }
Defensive patterns

Strategy: try-catch

Validate before calling

const exists = (await fetchSyncPost(API + "/getSession", {id}, APP_HEADER))?.code === 0;

Type guard

const isApiOk = (r: unknown): r is {code: number; msg?: string} => !!r && typeof (r as any).code === "number";

Try / catch

try { await store.remove(id); } catch (e) { refreshSessionList(); showMessage(e.message); }

Prevention

When it happens

Trigger: Calling remove(id) on an agent session whose backend session no longer exists, whose ID is invalid, or when the kernel request fails (network error producing an empty/undefined response, or a kernel-side failure without a msg field).

Common situations: Stale session list where the .sy/agent data was deleted on disk or by another client; workspace sync conflicts; kernel restarted with a different session store; temporary network/API failure while a session cleanup runs.

Related errors


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

Appendix: source

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

            }
            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);
            }
        }
    },

    async remove(id: string): Promise<void> {
        await waitForPendingSave(id);
        const resp = await fetchSyncPost(API + "/removeSession", {id}, APP_HEADER) as {code: number; msg?: string};
        if (!resp || resp.code !== 0) {
            throw new Error(resp?.msg || "Failed to remove agent session");
        }
        sessionRevisions.delete(id);
        sessionRuntimeRevisions.delete(id);
    },

    async rename(id: string, newTitle: string): Promise<void> {
        const session = await this.load(id);
        if (!session) { return; }
        session.title = newTitle;
        await this.save(session);
    },

    async setPermission(id: string, permissionMode: AgentPermissionMode): Promise<AgentPermissionMode> {
        await waitForPendingSave(id);
        const resp = await fetchSyncPost(API + "/setPermission", {
            sessionID: id,
            permissionMode,
        }, APP_HEADER) as {code: number; msg?: string; data?: {permissionMode?: AgentPermissionMode}};

View on GitHub (pinned to 9f775e8a12)