{"record":{"id":"d5642c47a7e7ba30","repo":"siyuan-note/siyuan","slug":"config-description-is-required-and-must-be-a-strin","errorCode":null,"errorMessage":"config.description is required and must be a string","messagePattern":"config\\.description is required and must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_agent.go","lineNumber":97,"sourceCode":"\t\t\t\t} else {\n\t\t\t\t\terr = fmt.Errorf(\"first argument must be a tool name string\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif c := call.Argument(1); isJsValueNotNull(c) {\n\t\t\t\t\tconfigObj := c.ToObject(rt)\n\t\t\t\t\tif configObj != nil {\n\t\t\t\t\t\tif titleValue := configObj.Get(\"title\"); goja.IsString(titleValue) {\n\t\t\t\t\t\t\ttitle = titleValue.String()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif descriptionValue := configObj.Get(\"description\"); goja.IsString(descriptionValue) {\n\t\t\t\t\t\t\tdescription = strings.TrimSpace(descriptionValue.String())\n\t\t\t\t\t\t\tif description == \"\" {\n\t\t\t\t\t\t\t\terr = fmt.Errorf(\"config.description must not be empty\")\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\terr = fmt.Errorf(\"config.description is required and must be a string\")\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif inputSchemaValue := configObj.Get(\"inputSchema\"); isJsValueNotNull(inputSchemaValue) {\n\t\t\t\t\t\t\tif inputSchema, err = jsCapabilitySchemaToGoSchema(rt, inputSchemaValue); err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\terr = fmt.Errorf(\"config.inputSchema is required\")\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif outputSchemaValue := configObj.Get(\"outputSchema\"); isJsValueNotNull(outputSchemaValue) {\n\t\t\t\t\t\t\tif outputSchema, err = jsCapabilitySchemaToGoSchema(rt, outputSchemaValue); err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif effectsValue := configObj.Get(\"effects\"); isJsValueNotNull(effectsValue) {\n\t\t\t\t\t\t\tif effects, err = jsCapabilityEffectsToGoEffects(rt, effectsValue); err != nil {\n\t\t\t\t\t\t\t\treturn","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/plugin/api_agent.go#L79-L115","documentation":"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.","triggerScenarios":"Omitting description from the config object entirely: { inputSchema: {...} }. Or passing a non-string: { description: 42, inputSchema: {...} } or { description: null, inputSchema: {...} }.","commonSituations":"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.","solutions":["Add a string-valued description field to the config object","Ensure description is a JS string primitive, not a number, object, or null"],"exampleFix":"// before\nawait siyuan.agent.registerCapability('myTool', {\n  inputSchema: { type: 'object' }\n}, handler);\n\n// after\nawait siyuan.agent.registerCapability('myTool', {\n  description: 'Extracts key points from a document',\n  inputSchema: { type: 'object' }\n}, handler);","handlingStrategy":"validation","validationCode":"if (typeof config.description !== 'string') {\n  throw new Error('config.description is required and must be a string');\n}\nawait siyuan.agent.registerCapability(name, config, handler);","typeGuard":"function hasStringDescription(config) {\n  return config != null && typeof config.description === 'string';\n}","tryCatchPattern":null,"preventionTips":["Always include a string-valued description field in the config object","Avoid using null/undefined or non-string types for description"],"tags":["plugin","agent","capability","validation","javascript"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}