siyuan-note/siyuan · error
capability name must not be empty
Error message
capability name must not be empty
What it means
The first argument to registerCapability() was a string, but after trimming whitespace it was empty. Every capability must have a non-empty name so the kernel can key it, expose it to the agent, and allow later unregistration by name.
Solutions
- Provide a non-empty, trimmed name string as the first argument
- Check the variable feeding the name for empty/whitespace-only values before registering
- Use a stable, descriptive identifier (e.g. "myplugin_search_notes")
Example fix
// before const name = " "; plugin.registerCapability(name, config, handler); // after const name = "myplugin_search_notes"; if (name.trim()) plugin.registerCapability(name, config, handler);
Defensive patterns
Strategy: validation
Validate before calling
if (typeof name === "string" && name.trim() === "") { throw new Error("capability name is empty"); } Type guard
const hasValidName = (n) => typeof n === "string" && n.trim().length > 0;
Try / catch
try { plugin.registerCapability(name, config, handler); } catch (e) { if (String(e).includes("name must not be empty")) { name = fallbackName; return plugin.registerCapability(name, config, handler); } throw e; } Prevention
- Never rely on unset constants for the tool name
- Trim and check names before registration
- Use plugin-id-prefixed names to guarantee uniqueness
When it happens
Trigger: registerCapability("", config, handler), registerCapability(" ", config, handler), or passing a variable that resolves to an empty string (e.g. an unset constant or an object lookup that returned "").
Common situations: Template placeholders like registerCapability(TOOL_NAME, ...) where TOOL_NAME was never set; config-driven registration where the tool name field is empty; building names via concatenation where a prefix/suffix variable is blank.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- config.description must not be empty
- registerCapability requires 3 arguments: name, config…
- unregisterCapability requires 1 argument: name
- Conf.Language(114)
- config.description is required and must be a string
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/378051521a50f79a.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_agent.go:76
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()
}
if descriptionValue := configObj.Get("description"); goja.IsString(descriptionValue) {
description = strings.TrimSpace(descriptionValue.String())
if description == "" {
err = fmt.Errorf("config.description must not be empty")
returnView on GitHub (pinned to 9f775e8a12)