siyuan-note/siyuan · error

invalid frontend capability

Error message

invalid frontend capability [%s]: %w

What it means

After building a validation tool from a frontend capability, buildCapabilitySet compiles its input/output schema with tools.CompileToolValidator. If the schema is malformed or unsupported the compile fails and the error is wrapped as 'invalid frontend capability [ID]' with the underlying reason attached via %w.

Solutions

  1. Read the wrapped %w cause in the error to see the exact schema defect
  2. Fix the capability's InputSchema/OutputSchema to be a valid, supported JSON Schema (correct type names, valid properties/required)
  3. Validate the schema offline with a JSON Schema validator before registering the capability
  4. Simplify the schema: drop unsupported keywords the compiler rejects

Example fix

// before
InputSchema: map[string]any{"type": "strng", "properties": ...}
// after
InputSchema: map[string]any{"type": "object", "properties": map[string]any{...}}
Defensive patterns

Strategy: validation

Validate before calling

if err := jsonschema.Validate(schemaDraft, cap.InputSchema); err != nil {
    return err
}

Prevention

When it happens

Trigger: A frontend capability registers with an InputSchema or OutputSchema that fails schema compilation (malformed JSON Schema, unsupported types, invalid required/properties structure), during buildCapabilitySet.

Common situations: Plugin authors hand-writing JSON Schema with typos or unsupported constructs; schemas generated dynamically that produce null/invalid types; schemas copied from OpenAPI definitions with constructs the validator does not support.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/2ce608cc3364d935. Report an issue: GitHub.

Appendix: source

Thrown at kernel/agent/capability.go:251

	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"
		}
		effects := tools.ToolEffects{}
		if frontend.Effects != nil {
			effects = *frontend.Effects
		}
		registration := &capabilityRegistration{
			ID:              frontend.ID,
			ModelName:       validationTool.Name,
			Title:           frontend.Title,
			Description:     frontend.Description,
			Source:          source,
			OwnerID:         frontend.OwnerID,
			OwnerName:       frontend.OwnerName,
			Runtime:         "browser",

View on GitHub (pinned to 9f775e8a12)