siyuan-note/siyuan · error
registerCapability requires 3 arguments: name, config, handl
Error message
registerCapability requires 3 arguments: name, config, handler
What it means
Thrown by the siyuan.agent.registerCapability JS API exposed to plugins when fewer than 3 arguments are passed. The API contract requires exactly three arguments: a capability name string, a config object, and a handler function. goja reports call.Arguments as a sparse array padded with undefined, so len(call.Arguments) < 3 means the JS caller omitted at least one argument.
Source
Thrown at kernel/plugin/api_agent.go:70
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
argErr := func() (err error) {
if len(call.Arguments) < 3 {
err = fmt.Errorf("registerCapability requires 3 arguments: name, config, handler")
return
} else {
if s := call.Argument(0); goja.IsString(s) {
name = strings.TrimSpace(s.String())
if name == "" {
err = fmt.Errorf("capability name must not be empty")
return
}
} else {
err = fmt.Errorf("first argument must be a tool name string")
return
}
if c := call.Argument(1); isJsValueNotNull(c) {
configObj := c.ToObject(rt)
if configObj != nil {
if titleValue := configObj.Get("title"); goja.IsString(titleValue) {
title = titleValue.String()View on GitHub (pinned to 251596fc0d)
Solutions
- Provide all three arguments: name (string), config (object with description and inputSchema), handler (function)
- Check the plugin's registerCapability call site against the current API signature in api_agent.go
Example fix
// before
await siyuan.agent.registerCapability('myTool', {
description: 'Does something',
inputSchema: { type: 'object', properties: {} }
});
// after
await siyuan.agent.registerCapability('myTool', {
description: 'Does something',
inputSchema: { type: 'object', properties: {} }
}, (args) => {
return { result: 'done' };
}); Defensive patterns
Strategy: try-catch
Validate before calling
if (arguments.length < 3) {
throw new Error('registerCapability needs (name, config, handler)');
}
await siyuan.agent.registerCapability(name, config, handler); Type guard
function isValidCapabilityCall(name, config, handler) {
return typeof name === 'string' && name.trim() !== ''
&& config !== null && config !== undefined
&& typeof handler === 'function';
} Try / catch
try {
await siyuan.agent.registerCapability(name, config, handler);
} catch (e) {
console.error('registerCapability failed:', e.message);
} Prevention
- Always pass exactly three arguments to registerCapability: name, config, handler
- Use TypeScript or JSDoc to enforce the argument count at development time
- Unit-test plugin capability registration with valid arguments before deployment
When it happens
Trigger: A plugin calls siyuan.agent.registerCapability('myTool', config) — omitting the handler. Or siyuan.agent.registerCapability(config, handler) — omitting the name. Any call with fewer than three positional arguments triggers this.
Common situations: Plugin developer forgets the handler argument; destructures or passes arguments dynamically and one is missing; copy-paste from an older API version that had fewer required arguments.
Related errors
- config.description must not be empty
- config.description is required and must be a string
- config.inputSchema is required
- second argument must be a config object
- unregisterCapability requires 1 argument: name
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/ab43c454dc19fb87.
Report an issue: GitHub.