siyuan-note/siyuan · error
panic during siyuan.client.fetch
Error message
panic during siyuan.client.fetch: %v
What it means
The actual HTTP request of siyuan.client.fetch runs on a background goroutine; any panic there (or a returned error) is converted into a rejection of the fetch promise with this message. It wraps unexpected kernel-side failures during request execution or response handling so plugin code sees a catchable error instead of crashing the runtime.
Solutions
- Wrap the call in try/catch or .catch() and handle the rejection gracefully
- Retry the request once after a short delay if the kernel was busy or restarting
- Check the kernel log for the underlying panic/error detail
- Verify the target API path exists and the payload size is reasonable
Example fix
// before
const res = await siyuan.client.fetch("/api/query/sql", { method: "POST", body: JSON.stringify({ stmt }) });
// after
let res;
try {
res = await siyuan.client.fetch("/api/query/sql", { method: "POST", body: JSON.stringify({ stmt }) });
} catch (e) {
console.error("siyuan.client.fetch failed:", e);
res = null;
} Defensive patterns
Strategy: try-catch
Validate before calling
async function safeKernelFetch(path, opts, retries = 1) {
for (let i = 0; i <= retries; i++) {
try { return await siyuan.client.fetch(path, opts); }
catch (e) { if (i === retries) throw e; await new Promise(r => setTimeout(r, 500)); }
}
} Try / catch
try {
const res = await siyuan.client.fetch(path, opts);
} catch (e) {
// every siyuan.client.fetch failure surfaces here; log and degrade gracefully
console.error("kernel fetch failed:", e);
} Prevention
- Always await inside try/catch — every fetch failure rejects the promise
- Add one retry with backoff for transient kernel load
- Keep request payloads small; check kernel logs for the underlying cause
When it happens
Trigger: A kernel-side panic while performing the HTTP request (e.g. transport failure handling, response body processing bug) or an error returned by the request path; the promise rejects with this wrapped message.
Common situations: Kernel unreachable or shutting down while a plugin request is in flight; very large or malformed responses triggering a processing bug; concurrent plugin requests during workspace close.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/70efe2d878e8fc41.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_client.go:106
}
}
}
}
}
}
}
runErr := p.worker.Run(func(rt *goja.Runtime) (_ any, err error) {
if argErr != nil {
err = argErr
return
}
go func() {
var err error
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic during siyuan.client.fetch: %v", r)
}
if err != nil {
p.worker.Run(func(rt *goja.Runtime) (_ any, _ error) {
if rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {
logging.LogErrorf("[plugin:%s] siyuan.client.fetch reject: %v", p.Name, rejectErr)
}
return
}, nil)
}
}()
targetURL := fmt.Sprintf("http://127.0.0.1:%s%s", util.ServerPort, path)
r := httpClient.R()
for k, v := range headers {
r.SetHeader(k, v)
}
r.SetHeader(model.XAuthTokenKey, p.token)View on GitHub (pinned to 9f775e8a12)