siyuan-note/siyuan · error

config.description must not be empty

Error message

config.description must not be empty

What it means

The config object's description property was a string, but it contained only whitespace after trimming. The description is required because it is shown to the AI agent to decide when to invoke the tool; a blank description would make the tool unusable.

Solutions

  1. Write a concise English description of what the tool does in config.description
  2. Trim-check the description value before registering
  3. Keep descriptions specific so the agent can pick the tool correctly

Example fix

// before
plugin.registerCapability("search", { description: "  ", inputSchema }, handler);
// after
plugin.registerCapability("search", { description: "Search notes in the workspace by keyword", inputSchema }, handler);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof config.description === "string" && !config.description.trim()) { throw new Error("config.description is blank"); }

Type guard

const hasDescription = (c) => typeof c?.description === "string" && c.description.trim().length > 0;

Try / catch

try { plugin.registerCapability(name, config, handler); } catch (e) { if (String(e).includes("config.description must not be empty")) { config.description = name + " tool"; return plugin.registerCapability(name, config, handler); } throw e; }

Prevention

When it happens

Trigger: registerCapability(name, { description: " ", inputSchema: {...} }, handler) or description sourced from an empty/whitespace user field.

Common situations: I18n lookup returning whitespace when a translation key is missing; template config with an unfilled description slot; copying a config and clearing the description.

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


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/65aa127a536ddef3. Report an issue: GitHub.

Appendix: source

Thrown at kernel/plugin/api_agent.go:93

					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")
							return
						}
						if inputSchemaValue := configObj.Get("inputSchema"); isJsValueNotNull(inputSchemaValue) {
							if inputSchema, err = jsCapabilitySchemaToGoSchema(rt, inputSchemaValue); err != nil {
								return
							}
						} else {
							err = fmt.Errorf("config.inputSchema is required")
							return
						}
						if outputSchemaValue := configObj.Get("outputSchema"); isJsValueNotNull(outputSchemaValue) {
							if outputSchema, err = jsCapabilitySchemaToGoSchema(rt, outputSchemaValue); err != nil {
								return
							}

View on GitHub (pinned to 9f775e8a12)