siyuan-note/siyuan · error
injectClient: %v
Error message
injectClient: %v
What it means
injectClient registers the siyuan.server object (fetch, SSE, WebSocket helpers) into the plugin's goja runtime. The whole function is wrapped in a recover() deferred handler so that any panic during injection — e.g. lo.Must0 failing on a Set error, rt.NewObject/NewPromise failures, or a runtime in a broken state — is converted into this error with the panic value embedded. It surfaces as plugin-load failure rather than crashing the kernel.
Source
Thrown at kernel/plugin/api_client.go:42
"net/http"
"strings"
"sync"
"sync/atomic"
"github.com/dop251/goja"
"github.com/lxzan/gws"
sse "github.com/r3labs/sse/v2"
"github.com/samber/lo"
"github.com/siyuan-note/logging"
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/util"
)
// injectClient adds siyuan.server to the goja context.
func injectClient(p *KernelPlugin, rt *goja.Runtime, siyuan *goja.Object) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("injectClient: %v", r)
}
}()
client := rt.NewObject()
lo.Must0(client.Set("fetch", rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
promise, resolve, reject := rt.NewPromise()
var argErr error
var path string
method := "GET"
headers := map[string]string{}
var bodyString *string
var bodyBytes *[]byte
if goja.IsString(call.Argument(0)) {
path = call.Argument(0).String()
} else {View on GitHub (pinned to 8641553a1f)
Solutions
- Check kernel logs for the full panic stack alongside the 'injectClient: %v' message
- Restart SiYuan and reload the plugin — the goja runtime is usually recreated fresh
- Disable recently installed/updated plugins to isolate one corrupting the runtime
- If reproducible, report with the panic value and plugin version; it is an internal-invariant failure, not a plugin API misuse
Defensive patterns
Strategy: try-catch
Try / catch
// plugin host side (Go): injectClient already recovers; log and fail plugin load gracefully
if err := injectClient(p, rt, siyuan); err != nil {
logging.LogErrorf("[plugin:%s] injectClient failed: %v", p.Name, err)
return err
} Prevention
- Keep the goja runtime alive and healthy during plugin load; avoid tearing down workers mid-injection
- Check kernel logs for the panic value accompanying 'injectClient:'
- Reproduce with a minimal plugin to rule out runtime state corruption
- Update SiYuan — this indicates a host-side internal fault, not plugin code misuse
When it happens
Trigger: A panic occurs while building the client object: goja runtime is closed or exhausted, a client.Set call errors (propagated by lo.Must0), or an internal invariant in the client setup (e.g. resolving the kernel HTTP endpoint) panics.
Common situations: Plugin worker runtime torn down mid-injection; port/endpoint resolution failure inside the client closure triggering a panic during setup; a bug/regression in the plugin host rather than in plugin code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- panic during siyuan.client.fetch: %v
- injectEvent: %v
- injectLogger: %v
- panic during siyuan.storage.put: %v
- panic during siyuan.storage.remove: %v
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/bc6785656b9db158.
Report an issue: GitHub.