siyuan-note/siyuan · error
first argument must be a tool name string
Error message
first argument must be a tool name string
What it means
The first argument to registerCapability() was not a string. The runtime checks goja.IsString on argument 0 and rejects any non-string type (number, object, undefined, null, boolean). Capability names must be strings because they become tool identifiers.
Solutions
- Ensure the first argument is a plain string tool name
- Reorder arguments to (name, config, handler) if they were swapped
- Coerce or validate the name with typeof name === "string" before calling
Example fix
// before
plugin.registerCapability(config, handler);
// after
plugin.registerCapability("myplugin_tool", config, handler); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof name !== "string") { throw new TypeError("capability name must be a string, got " + typeof name); } Type guard
const isName = (v) => typeof v === "string";
Try / catch
try { plugin.registerCapability(name, config, handler); } catch (e) { if (String(e).includes("first argument must be a tool name string")) { throw new TypeError("Fix argument order: (name, config, handler)"); } throw e; } Prevention
- Remember the argument order: name first, config second, handler third
- Type-check the name variable before calling
- Avoid passing option objects as the first argument
When it happens
Trigger: registerCapability(123, config, handler), passing an options object as the first argument (registerCapability(config, handler)), or a variable holding undefined/null because an earlier lookup failed.
Common situations: Swapped argument order — developers often pass config first; a name constant imported from a module that is actually an object; JSON-driven plugin config where the name field is missing so the lookup yields undefined.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- second argument must be a config object
- third argument must be a handler function
- capability name must not be empty
- config.description is required and must be a string
- config.description must not be empty
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/9288109a9031a0c0.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_agent.go:80
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()
}
if descriptionValue := configObj.Get("description"); goja.IsString(descriptionValue) {
description = strings.TrimSpace(descriptionValue.String())
if description == "" {
err = fmt.Errorf("config.description must not be empty")
return
}
} else {
err = fmt.Errorf("config.description is required and must be a string")
returnView on GitHub (pinned to 9f775e8a12)