{"record":{"id":"6de4ac942c643e0e","repo":"siyuan-note/siyuan","slug":"config-inputschema-is-required","errorCode":null,"errorMessage":"config.inputSchema is required","messagePattern":"config\\.inputSchema is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_agent.go","lineNumber":105,"sourceCode":"\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\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif actionEffectsValue := configObj.Get(\"actionEffects\"); isJsValueNotNull(actionEffectsValue) {\n\t\t\t\t\t\t\tif actionEffects, err = jsCapabilityActionEffectsToGoEffects(rt, actionEffectsValue); 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}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_agent.go#L87-L123","documentation":"The config object did not include an inputSchema property (it was missing, undefined, or null). inputSchema is required because it defines the JSON Schema of the arguments the agent will pass to the capability handler; without it the kernel cannot validate or describe the tool's inputs.","triggerScenarios":"registerCapability(name, { description: \"...\" }, handler) with inputSchema omitted, or inputSchema explicitly set to null.","commonSituations":"Migrating from an older registration API that had no schema requirement; configs shared between plugins where the schema section was dropped; assuming inputSchema is optional like outputSchema.","solutions":["Add an inputSchema JSON-Schema object describing the handler's arguments (e.g. { type: \"object\", properties: {...} })","Use a minimal { type: \"object\" } schema if the tool takes no arguments","Check that inputSchema is not set to null"],"exampleFix":"// before\nplugin.registerCapability(\"search\", { description: \"Search notes\" }, handler);\n// after\nplugin.registerCapability(\"search\", { description: \"Search notes\", inputSchema: { type: \"object\", properties: { query: { type: \"string\" } }, required: [\"query\"] } }, handler);","handlingStrategy":"validation","validationCode":"if (!config?.inputSchema || config.inputSchema === null) { throw new Error(\"config.inputSchema is required\"); }","typeGuard":"const hasInputSchema = (c) => c != null && c.inputSchema != null && typeof c.inputSchema === \"object\";","tryCatchPattern":"try { plugin.registerCapability(name, config, handler); } catch (e) { if (String(e).includes(\"config.inputSchema is required\")) { config.inputSchema = { type: \"object\" }; return plugin.registerCapability(name, config, handler); } throw e; }","preventionTips":["Always declare an inputSchema, even a minimal { type: \"object\" } for no-arg tools","Model schemas after the plugin samples","Note outputSchema is optional but inputSchema is not"],"tags":["plugin-api","missing-property","json-schema"],"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"}