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
Thrown by siyuan.agent.registerCapability when config.description is either missing entirely (undefined) or present but not a string (e.g., a number or object). The code checks goja.IsString(descriptionValue) — if the value is not a string type, this branch fires.
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 {
returnView on GitHub (pinned to 251596fc0d)
Solutions
- Add a string-valued description field to the config object
- Ensure description is a JS string primitive, not a number, object, or null
Example fix
// before
await siyuan.agent.registerCapability('myTool', {
inputSchema: { type: 'object' }
}, handler);
// after
await siyuan.agent.registerCapability('myTool', {
description: 'Extracts key points from a document',
inputSchema: { type: 'object' }
}, handler); Defensive patterns
Strategy: validation
Validate before calling
if (typeof config.description !== 'string') {
throw new Error('config.description is required and must be a string');
}
await siyuan.agent.registerCapability(name, config, handler); Type guard
function hasStringDescription(config) {
return config != null && typeof config.description === 'string';
} Prevention
- Always include a string-valued description field in the config object
- Avoid using null/undefined or non-string types for description
When it happens
Trigger: Omitting description from the config object entirely: { inputSchema: {...} }. Or passing a non-string: { description: 42, inputSchema: {...} } or { description: null, inputSchema: {...} }.
Common situations: Plugin developer forgets the description field; uses a non-string type (number, boolean) by mistake; the config object is built dynamically and the description key was never set.
Related errors
- registerCapability requires 3 arguments: name, config, handl
- config.description must not be empty
- config.inputSchema is required
- second argument must be a config object
- unregisterCapability requires 1 argument: name
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/d5642c47a7e7ba30.
Report an issue: GitHub.