siyuan-note/siyuan · error
injectAgent: %v
Error message
injectAgent: %v
What it means
injectAgent injects the siyuan.agent API into a kernel plugin's goja JS sandbox. The whole injection is wrapped in a recover() so any panic inside goja (runtime mismatch, nil object, scripting engine error) is converted into this wrapped error instead of crashing the kernel.
Source
Thrown at kernel/plugin/api_agent.go:49
// pluginCapabilityModelName 构造内核插件能力向模型暴露的函数名。
func pluginCapabilityModelName(pluginName, capabilityName string) string {
name := fmt.Sprintf("plugin__%s__%s", util.SanitizeName(pluginName), util.SanitizeName(capabilityName))
hash := sha256.Sum256([]byte(pluginName + "\x00" + capabilityName))
suffix := fmt.Sprintf("__%x", hash[:6])
if len(name) > maxCapabilityModelNameLen-len(suffix) {
name = name[:maxCapabilityModelNameLen-len(suffix)]
}
return name + suffix
}
const maxCapabilityModelNameLen = 64
// injectAgent 将 siyuan.agent 注入插件 JS 沙箱。
func injectAgent(p *KernelPlugin, rt *goja.Runtime, siyuan *goja.Object) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("injectAgent: %v", r)
}
}()
agentAPI := rt.NewObject()
// siyuan.agent.registerCapability(name, config, handler) 返回 Promise<IRegisteredCapability>。
lo.Must0(agentAPI.Set("registerCapability", rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
promise, resolve, reject := rt.NewPromise()
var name string
var title string
var description string
var effects *tools.ToolEffects
var actionEffects map[string]tools.ToolEffects
var inputSchema *tools.ToolSchema
var outputSchema *tools.ToolSchema
var handler goja.Callable
View on GitHub (pinned to 8641553a1f)
Solutions
- Read the wrapped %v payload to identify the underlying panic and fix the root cause.
- Ensure the plugin worker's goja runtime is alive and only accessed from its own run loop when injection happens.
- Retry plugin load after fixing; if reproducible with a minimal plugin, report it as a kernel bug since plugin JS cannot normally panic Go code.
Defensive patterns
Strategy: try-catch
Try / catch
// Kernel-side recover already wraps the panic; consumers of plugin load should catch:
if err := injectAgent(p, rt, siyuan); err != nil {
log.Fatalf("plugin %s agent injection failed: %v", p.Name, err)
} Prevention
- Only touch the goja runtime from its owning worker goroutine.
- Keep goja and kernel versions in sync when rebuilding.
- Report reproducible panics with a minimal plugin — they indicate kernel bugs.
When it happens
Trigger: Plugin loading/initialization reaches injectAgent and a panic occurs while building the agent API object or registering registerCapability on the goja runtime — surfaced as "injectAgent: <panic value>".
Common situations: Buggy plugin runtime setup, goja runtime closed or used from the wrong goroutine, or an internal kernel regression while wiring the agent API during plugin startup.
Related errors
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/49a29a515ccd9d78.
Report an issue: GitHub.