siyuan-note/siyuan · error

config.description must not be empty

Error message

config.description must not be empty

What it means

Thrown by siyuan.agent.registerCapability when config.description is a string but trims to empty after strings.TrimSpace. The description is required because it is exposed to the AI model as the tool's purpose — an empty description would make the tool invisible/ambiguous to the model.

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 251596fc0d)

Solutions

  1. Provide a meaningful, non-empty description string in the config object
  2. If description is dynamically sourced, validate it is non-empty before calling registerCapability

Example fix

// before
await siyuan.agent.registerCapability('myTool', {
  description: '',
  inputSchema: { type: 'object' }
}, handler);

// after
await siyuan.agent.registerCapability('myTool', {
  description: 'Summarizes the current document',
  inputSchema: { type: 'object' }
}, handler);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

function hasValidDescription(config) {
  return typeof config?.description === 'string' && config.description.trim().length > 0;
}

Prevention

When it happens

Trigger: Passing config = { description: '', inputSchema: {...} } or config = { description: ' ', inputSchema: {...} } — description is present and is a string, but empty or whitespace-only.

Common situations: Plugin developer uses a placeholder empty string intending to fill it later; description is loaded from a config file that has an empty value; copy-paste from a template that left description blank.

Related errors


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