{"record":{"id":"9288109a9031a0c0","repo":"siyuan-note/siyuan","slug":"first-argument-must-be-a-tool-name-string","errorCode":null,"errorMessage":"first argument must be a tool name string","messagePattern":"first argument must be a tool name string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_agent.go","lineNumber":80,"sourceCode":"\t\tvar effects *tools.ToolEffects\n\t\tvar actionEffects map[string]tools.ToolEffects\n\t\tvar inputSchema *tools.ToolSchema\n\t\tvar outputSchema *tools.ToolSchema\n\t\tvar handler goja.Callable\n\n\t\targErr := func() (err error) {\n\t\t\tif len(call.Arguments) < 3 {\n\t\t\t\terr = fmt.Errorf(\"registerCapability requires 3 arguments: name, config, handler\")\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\tif s := call.Argument(0); goja.IsString(s) {\n\t\t\t\t\tname = strings.TrimSpace(s.String())\n\t\t\t\t\tif name == \"\" {\n\t\t\t\t\t\terr = fmt.Errorf(\"capability name must not be empty\")\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\terr = fmt.Errorf(\"first argument must be a tool name string\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif c := call.Argument(1); isJsValueNotNull(c) {\n\t\t\t\t\tconfigObj := c.ToObject(rt)\n\t\t\t\t\tif configObj != nil {\n\t\t\t\t\t\tif titleValue := configObj.Get(\"title\"); goja.IsString(titleValue) {\n\t\t\t\t\t\t\ttitle = titleValue.String()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif descriptionValue := configObj.Get(\"description\"); goja.IsString(descriptionValue) {\n\t\t\t\t\t\t\tdescription = strings.TrimSpace(descriptionValue.String())\n\t\t\t\t\t\t\tif description == \"\" {\n\t\t\t\t\t\t\t\terr = fmt.Errorf(\"config.description must not be empty\")\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\terr = fmt.Errorf(\"config.description is required and must be a string\")\n\t\t\t\t\t\t\treturn","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_agent.go#L62-L98","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nplugin.registerCapability(config, handler);\n// after\nplugin.registerCapability(\"myplugin_tool\", config, handler);","handlingStrategy":"type-guard","validationCode":"if (typeof name !== \"string\") { throw new TypeError(\"capability name must be a string, got \" + typeof name); }","typeGuard":"const isName = (v) => typeof v === \"string\";","tryCatchPattern":"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; }","preventionTips":["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"],"tags":["plugin-api","type-error","argument-order"],"backgroundTag":"invalid-argument-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}