siyuan-note/siyuan · error · Error

window.siyuan.languages._kernel[28] or…

Error message

window.siyuan.languages._kernel[28] or data.msg/data.message from failed response

What it means

fetchAIEditorSSE throws a generic error when the AI editor streaming response is not OK. It first tries to extract a message from the response body's `msg` or `message` JSON fields, falling back to `window.siyuan.languages._kernel[28]` (a localized network/parse failure string) when the body is not JSON. This surfaces backend failure reasons to the UI in a uniform way.

Solutions

  1. Check the network tab / kernel logs for the actual HTTP status and response body of the AI request
  2. Verify the AI provider configuration (API key, base URL, model) in Settings - AI
  3. If behind a proxy, ensure it passes through JSON error bodies rather than HTML error pages
  4. Retry the request; transient backend outages commonly produce this

Example fix

// before: backend returns HTML error page -> message falls back to generic i18n string
// after: surface status code too
const data = await response.json().catch(() => null);
message = data?.msg || data?.message || `AI request failed with status ${response.status}`;
Defensive patterns

Strategy: try-catch

Validate before calling

if (!window.siyuan.config?.ai) { throw new Error("AI is not configured"); }

Type guard

const isFailedResponse = (data: unknown): data is {msg?: string; message?: string} => typeof data === "object" && data !== null && ("msg" in data || "message" in data);

Try / catch

try {
    await fetchAIEditorSSE(url, data, onEvent);
} catch (e) {
    showMessage(e.message || window.siyuan.languages._kernel[28]); // surface and offer retry
}

Prevention

When it happens

Trigger: The kernel returns a non-OK HTTP response to an AI editor SSE request and the JSON body has neither `msg` nor `message`, or the body is not JSON at all (e.g. an HTML error page from a proxy, or an empty body).

Common situations: AI backend unreachable or misconfigured behind a reverse proxy that returns HTML 502/504 pages; API key missing so the kernel returns a JSON error without `msg`; gateway timeouts returning empty bodies.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at app/src/ai/editorSSE.ts:110

    onEvent: (event: TAIEditorSSEEvent) => void,
    signal: AbortSignal,
) => {
    const response = await fetch("/api/ai/editor/chat", {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify(request),
        signal,
    });
    const contentType = response.headers.get("Content-Type") || "";
    if (!response.ok || !contentType.includes("text/event-stream")) {
        let message = window.siyuan.languages._kernel[28];
        try {
            const data = await response.json();
            message = data?.msg || data?.message || message;
        } catch (e) {
            // 响应不是 JSON 时使用统一错误文案。
        }
        throw new Error(message);
    }
    const reader = response.body?.getReader();
    if (!reader) {
        throw new Error(window.siyuan.languages._kernel[28]);
    }
    const decoder = new TextDecoder();
    const parserState = createAIEditorSSEParserState();
    let terminalReceived = false;
    while (true) {
        const result = await reader.read();
        if (result.done) {
            break;
        }
        parseAIEditorSSE(parserState, decoder.decode(result.value, {stream: true})).forEach(event => {
            terminalReceived = terminalReceived || event.type === "done" || event.type === "error";
            onEvent(event);
        });
    }

View on GitHub (pinned to 9f775e8a12)