{"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/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_agent.go#L79-L115","documentation":"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.","triggerScenarios":"registerCapability(name, { title: \"My tool\", inputSchema }, handler) with description omitted entirely, or description: 123 / description: null.","commonSituations":"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.","solutions":["Add a non-empty string description to the config object","Verify the key is spelled exactly description","Ensure the value is a string, not a number, boolean, or object"],"exampleFix":"// before\nplugin.registerCapability(\"search\", { title: \"Search\", inputSchema }, handler);\n// after\nplugin.registerCapability(\"search\", { title: \"Search\", description: \"Search notes by keyword\", inputSchema }, handler);","handlingStrategy":"validation","validationCode":"if (typeof config?.description !== \"string\") { throw new Error(\"config.description must be a string\"); }","typeGuard":"const hasStringDescription = (c) => c != null && typeof c.description === \"string\";","tryCatchPattern":"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; }","preventionTips":["Spell the key exactly as description (not desc)","Include description in every config template/boilerplate","Validate the full config shape before registration"],"tags":["plugin-api","missing-property","config-validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}