siyuan-note/siyuan · error

config.description is required and must be a string

Error message

config.description is required and must be a string

What it means

The config object passed to registerCapability() did not include a description property that is a string (it was missing, undefined, null, or a non-string type). The API requires description to be a string since it is surfaced to the agent runtime.

Solutions

  1. Add a non-empty string description to the config object
  2. Verify the key is spelled exactly description
  3. Ensure the value is a string, not a number, boolean, or object

Example fix

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

Strategy: validation

Validate before calling

if (typeof config?.description !== "string") { throw new Error("config.description must be a string"); }

Type guard

const hasStringDescription = (c) => c != null && typeof c.description === "string";

Try / catch

try { plugin.registerCapability(name, config, handler); } catch (e) { if (String(e).includes("config.description is required")) { console.error("Add description to capability config for", name); } throw e; }

Prevention

When it happens

Trigger: registerCapability(name, { title: "My tool", inputSchema }, handler) with description omitted entirely, or description: 123 / description: null.

Common situations: Older plugin code written before description became mandatory; configs built programmatically where the description key was never assigned; renamed key (e.g. desc) that the API does not read.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at kernel/plugin/api_agent.go:97

				} 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
							}
						}
						if effectsValue := configObj.Get("effects"); isJsValueNotNull(effectsValue) {
							if effects, err = jsCapabilityEffectsToGoEffects(rt, effectsValue); err != nil {
								return

View on GitHub (pinned to 9f775e8a12)