{"record":{"id":"2ce608cc3364d935","repo":"siyuan-note/siyuan","slug":"invalid-frontend-capability-s-w","errorCode":null,"errorMessage":"invalid frontend capability [%s]: %w","messagePattern":"invalid frontend capability \\[(.+?)\\]: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/agent/capability.go","lineNumber":232,"sourceCode":"\tfor _, frontend := range frontendCapabilities {\n\t\tif !validFrontendCapabilityID(frontend.ID) {\n\t\t\treturn nil, fmt.Errorf(\"invalid frontend capability ID: %s\", frontend.ID)\n\t\t}\n\t\tif strings.TrimSpace(frontend.Description) == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"frontend capability description is required: %s\", frontend.ID)\n\t\t}\n\t\tif !capabilityAllowed(frontend.ID, accessContext) {\n\t\t\tcontinue\n\t\t}\n\t\tvalidationTool := &tools.Tool{\n\t\t\tName:         frontendCapabilityModelName(frontend.ID),\n\t\t\tDescription:  frontend.Description,\n\t\t\tInputSchema:  frontend.InputSchema,\n\t\t\tOutputSchema: frontend.OutputSchema,\n\t\t}\n\t\tvalidator, err := tools.CompileToolValidator(validationTool)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid frontend capability [%s]: %w\", frontend.ID, err)\n\t\t}\n\t\tsource := \"native\"\n\t\tif strings.HasPrefix(frontend.ID, \"plugin/frontend/\") {\n\t\t\tsource = \"plugin\"\n\t\t}\n\t\teffects := tools.ToolEffects{}\n\t\tif frontend.Effects != nil {\n\t\t\teffects = *frontend.Effects\n\t\t}\n\t\tregistration := &capabilityRegistration{\n\t\t\tID:              frontend.ID,\n\t\t\tModelName:       validationTool.Name,\n\t\t\tTitle:           frontend.Title,\n\t\t\tDescription:     frontend.Description,\n\t\t\tSource:          source,\n\t\t\tOwnerID:         frontend.OwnerID,\n\t\t\tOwnerName:       frontend.OwnerName,\n\t\t\tRuntime:         \"browser\",","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/agent/capability.go#L214-L250","documentation":"After id and description checks pass, capability.go calls tools.CompileToolValidator on a synthetic Tool built from the frontend capability's InputSchema/OutputSchema. If compilation fails (invalid JSON Schema, unsupported keywords, schema does not compile to a validator), the error is wrapped with 'invalid frontend capability [<id>]: %w' and returned.","triggerScenarios":"A frontend capability supplies an InputSchema or OutputSchema that is not a valid JSON Schema (wrong 'type' value, malformed 'properties', unsupported keyword for the compiler, $ref that cannot be resolved, or array/object schemas missing required fields).","commonSituations":"Plugin author writes a JSON Schema by hand and mistypes a keyword; schema uses draft-07-only features not supported by the kernel's compiler; OutputSchema declared but not a valid schema object; properties typed as strings instead of schema objects; enum/array mixed incorrectly.","solutions":["Read the wrapped error — it is the compiler's specific complaint about the schema.","Validate the InputSchema/OutputSchema against JSON Schema draft used by tools.CompileToolValidator before submitting the capability.","Strip unsupported keywords and simplify the schema to primitive types first; add complexity incrementally.","Use the same ToolInputSchema shape as native kernel tools as a reference template."],"exampleFix":"// before\ncap := FrontendCapability{ID: id, Description: 'x', InputSchema: map[string]any{'type': 'obj'}} // typo\n// after\nimport 'github.com/siyuan-note/siyuan/kernel/tools'\ncap := FrontendCapability{ID: id, Description: 'x',\n    InputSchema: map[string]any{'type': 'object', 'properties': map[string]any{'q': map[string]any{'type':'string'}}, 'required': []string{'q'}},\n}\nif _, err := tools.CompileToolValidator(&tools.Tool{Name: 't', InputSchema: cap.InputSchema}); err != nil { return err }","handlingStrategy":"validation","validationCode":"validator, err := tools.CompileToolValidator(&tools.Tool{Name: 'tmp', InputSchema: frontend.InputSchema, OutputSchema: frontend.OutputSchema})\nif err != nil { return fmt.Errorf('schema rejected before submit: %w', err) }","typeGuard":null,"tryCatchPattern":"if err := buildCapabilitySet(...); err != nil {\n    if strings.Contains(err.Error(), 'invalid frontend capability') { /* read wrapped schema error, fix and retry */ }\n    return err\n}","preventionTips":["Validate InputSchema/OutputSchema with tools.CompileToolValidator before submitting.","Use simple primitive types first; add complexity incrementally.","Strip JSON-Schema keywords the compiler does not support.","Model capability schemas on existing native kernel tools."],"tags":["agent","capability","json-schema","validation","go"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}