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
- Check the network tab / kernel logs for the actual HTTP status and response body of the AI request
- Verify the AI provider configuration (API key, base URL, model) in Settings - AI
- If behind a proxy, ensure it passes through JSON error bodies rather than HTML error pages
- 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
- Validate AI configuration before issuing requests
- Avoid proxies that replace JSON errors with HTML pages
- Monitor kernel logs for AI backend failures
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 editor request timeout
- AI editor stream idle timeout
- generate image failed
- access to private/internal IP is prohibited
- access to private/internal IP is prohibited
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)