siyuan-note/siyuan · error · Error

Failed to update agent session permission

Error message

Failed to update agent session permission

What it means

Thrown by SessionStore.setPermission() when POST /api/ai/agent/setPermission replies with a falsy body or code !== 0. The endpoint accepts a sessionID plus an AgentPermissionMode ('confirm' | 'allowSession'); a non-zero code typically means the session does not exist, the mode value is invalid, or authorization failed.

Source

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

        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}};
        if (!resp || resp.code !== 0) {
            throw new Error(resp?.msg || "Failed to update agent session permission");
        }
        return resp.data?.permissionMode || permissionMode;
    },

    getRevision(id: string): number {
        return sessionRevisions.get(id) ?? 0;
    },

    newSessionId,
};

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Validate permissionMode is one of 'confirm' or 'allowSession' before the call.
  2. Wrap the call and on failure re-check the session via load(id); if absent, drop the local entry instead of retrying blindly.
  3. Read resp.msg and show it to the user so the actual kernel-side reason is visible.
  4. If the kernel was just restarted, wait for the WebSocket reconnect event before retrying.

Example fix

// before
await SessionStore.setPermission(id, mode);
// after
const valid: AgentPermissionMode[] = ['confirm', 'allowSession'];
if (!valid.includes(mode)) { throw new Error('Invalid permission mode'); }
try { await SessionStore.setPermission(id, mode); }
catch (e) { showMessage(e.message); }
Defensive patterns

Strategy: validation

Validate before calling

const valid: AgentPermissionMode[] = ['confirm', 'allowSession'];
if (!valid.includes(mode)) throw new Error('Invalid permission mode: ' + String(mode));

Type guard

function isPermissionMode(v: unknown): v is AgentPermissionMode { return v === 'confirm' || v === 'allowSession'; }

Try / catch

try { await SessionStore.setPermission(id, mode); }
catch (e) { showMessage(e.message || 'Failed to update agent session permission'); }

Prevention

When it happens

Trigger: Calling setPermission with a session id that no longer exists on the server, passing a permissionMode outside the allowed union, hitting the endpoint while not authenticated, or the kernel being unreachable so fetchSyncPost returns null.

Common situations: Permission toggle clicked right after the session was deleted elsewhere; plugin/frontend out of sync with backend enum values after a partial upgrade; read-only / lock mode active; transport drop mid-call.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/9c7470f0c63bd0fc. Report an issue: GitHub.