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
Thrown by siyuan.agent.registerCapability when call.Argument(0) fails goja.IsString — the first argument exists but is not a JS string (e.g., a number, object, boolean, or symbol). The capability name must be a string because it is used to build the tool's internal identifier.
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 251596fc0d)
Solutions
- Ensure the first argument is a string literal or a variable known to hold a string
- Use String(name) coercion if the value might be non-string, or validate with typeof name === 'string' before calling
Example fix
// before
await siyuan.agent.registerCapability({ name: 'myTool' }, config, handler);
// after
await siyuan.agent.registerCapability('myTool', config, handler); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof name !== 'string') {
throw new TypeError('Capability name must be a string');
}
await siyuan.agent.registerCapability(name, config, handler); Type guard
function isStringArg(v) {
return typeof v === 'string';
} Prevention
- Pass string literals or verified string variables as the capability name
- Coerce with String(name) only if you are certain the value is meaningfully string-like
When it happens
Trigger: Passing a number (registerCapability(42, ...)), an object (registerCapability({name: 'x'}, ...)), or undefined/null as the first argument. In goja, passing undefined explicitly is not a string.
Common situations: Plugin passes a configuration object first by mistake; uses a numeric ID instead of a string name; the first argument comes from an untyped source (JSON.parse result with unexpected types).
Related errors
- third argument must be a handler function
- registerCapability requires 3 arguments: name, config, handl
- config.description must not be empty
- config.description is required and must be a string
- config.inputSchema is required
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/9288109a9031a0c0.
Report an issue: GitHub.