siyuan-note/siyuan · error

capability name must not be empty

Error message

capability name must not be empty

What it means

Thrown by siyuan.agent.registerCapability when the first argument is a string but trims to empty. The capability name is used to construct the model-facing tool name via pluginCapabilityModelName, which sanitizes and hashes it, so an empty name would produce an ambiguous tool identity.

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")
								return

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Pass a non-empty, descriptive capability name as the first argument
  2. If the name is dynamically generated, validate it is non-empty before calling registerCapability

Example fix

// before
await siyuan.agent.registerCapability('', config, handler);

// after
await siyuan.agent.registerCapability('summarize-note', config, handler);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof name !== 'string' || name.trim() === '') {
  throw new Error('Capability name must be a non-empty string');
}
await siyuan.agent.registerCapability(name, config, handler);

Type guard

function isValidCapabilityName(name) {
  return typeof name === 'string' && name.trim().length > 0;
}

Prevention

When it happens

Trigger: Calling registerCapability('', config, handler), or registerCapability(' ', config, handler) — strings that are empty or contain only whitespace after strings.TrimSpace.

Common situations: Plugin uses a variable for the capability name that was initialized but never assigned; a template/placeholder string was left in place; dynamic name generation produced an empty result.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/378051521a50f79a. Report an issue: GitHub.