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

  1. Read the wrapped %v payload to identify the underlying panic and fix the root cause.
  2. Ensure the plugin worker's goja runtime is alive and only accessed from its own run loop when injection happens.
  3. 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

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.