siyuan-note/siyuan · error
frontend capability description is required: %s
Error message
frontend capability description is required: %s
What it means
capability.go checks strings.TrimSpace(frontend.Description) == '' right after the id check and returns this formatted error. Even with a valid id, a capability whose description is blank (or only whitespace) is rejected because the description is what the model reads to decide when to call the capability.
Source
Thrown at kernel/agent/capability.go:219
OwnerName: tool.OwnerName,
Runtime: runtime,
Tool: tool,
Validator: validator,
InputSchema: tool.InputSchema,
OutputSchema: tool.OutputSchema,
AccessContext: accessContext,
}
if err := set.add(registration); err != nil {
return nil, err
}
}
for _, frontend := range frontendCapabilities {
if !validFrontendCapabilityID(frontend.ID) {
return nil, fmt.Errorf("invalid frontend capability ID: %s", frontend.ID)
}
if strings.TrimSpace(frontend.Description) == "" {
return nil, fmt.Errorf("frontend capability description is required: %s", frontend.ID)
}
if !capabilityAllowed(frontend.ID, accessContext) {
continue
}
validationTool := &tools.Tool{
Name: frontendCapabilityModelName(frontend.ID),
Description: frontend.Description,
InputSchema: frontend.InputSchema,
OutputSchema: frontend.OutputSchema,
}
validator, err := tools.CompileToolValidator(validationTool)
if err != nil {
return nil, fmt.Errorf("invalid frontend capability [%s]: %w", frontend.ID, err)
}
source := "native"
if strings.HasPrefix(frontend.ID, "plugin/frontend/") {
source = "plugin"
}View on GitHub (pinned to 251596fc0d)
Solutions
- Always supply a non-empty, meaningful description (it is shown to the model).
- Trim and assert non-empty at the frontend registration site before posting to the kernel.
- If i18n lookup fails, fall back to a hardcoded English description rather than empty.
- Validate the capability payload (id + description) with a shared schema on both sides.
Example fix
// before
cap := FrontendCapability{ID: id, Description: ''}
// after
desc := strings.TrimSpace(localizedDesc)
if desc == '' { desc = 'Default capability description' }
cap := FrontendCapability{ID: id, Description: desc} Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(frontend.Description) == '' { frontend.Description = 'Default capability description' } Try / catch
if err := buildCapabilitySet(...); err != nil {
if strings.Contains(err.Error(), 'description is required') { /* set fallback and retry */ }
return err
} Prevention
- Always supply a non-empty description; it is shown to the model.
- Fall back to a hardcoded English string if i18n lookup returns empty.
- Validate description non-empty at the registration site before posting.
- Share a capability-payload validator between frontend and kernel.
When it happens
Trigger: A frontend capability is sent with description '', description consisting of only spaces/tabs, or a description field that was supposed to be localized but resolved to empty.
Common situations: Plugin registers a capability with description pulled from an i18n key that was not yet translated; refactor removed the description; JSON marshal omitted the field so it defaults to empty; the description was set from a runtime variable that evaluated to ''.
Related errors
- invalid frontend capability ID: %s
- invalid frontend capability [%s]: %w
- registerCapability requires 3 arguments: name, config, handl
- capability name must not be empty
- config.description must not be empty
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/dd6ad746b9caf708.
Report an issue: GitHub.