siyuan-note/siyuan · error

invalid frontend capability ID

Error message

invalid frontend capability ID: %s

What it means

Raised by buildCapabilitySet when a frontend capability declared by a plugin fails the validFrontendCapabilityID check. Every frontend capability must use a recognized/valid ID format from the allowed capability namespace; an unknown or malformed ID aborts capability-set construction so unregistered capabilities can never be exposed to or invoked by the model.

Solutions

  1. Change the plugin's frontend capability ID to a value accepted by validFrontendCapabilityID (use a registered built-in ID or the sanctioned custom-ID format).
  2. Update the plugin to the current API version if a capability ID was renamed or removed in a recent release.
  3. Disable or uninstall the offending plugin to restore agent functionality.
  4. Check plugin code for typos in the ID string and against the plugin-sample reference implementation for the correct declaration.

Example fix

// before: plugin declares an arbitrary capability ID
plugin.addFrontendCapability({ id: "myCustomRunner", description: "Run tasks" })
// after: use a valid registered ID
plugin.addFrontendCapability({ id: "queryBlockDoc", description: "Query blocks by SQL" })
Defensive patterns

Strategy: validation

Validate before calling

function hasValidCapabilityID(cap) {
  return VALID_FRONTEND_CAPABILITY_IDS.includes(cap.id) && typeof cap.description === "string" && cap.description.trim() !== ""
}

Try / catch

caps, err := buildCapabilitySet(frontendCapabilities, accessContext)
if err != nil {
    // identify the offending plugin by the ID in the message and disable/update it
}

Prevention

When it happens

Trigger: In capability.go (~line 235): during buildCapabilitySet, iterating frontendCapabilities, a capability's frontend.ID does not pass validFrontendCapabilityID — e.g. a plugin registers a tool with a made-up or wrongly formatted/renamed ID, or a renamed built-in ID is still referenced by stale plugin code.

Common situations: A plugin declares a custom frontend tool whose ID is not in the valid capability registry; a SiYuan upgrade renamed/retired a capability ID while an outdated plugin still declares the old one; a typo in a capability ID string in plugin code; copying a sample plugin and editing the ID to an unsupported value.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at kernel/agent/capability.go:235

			Description:   tool.Description,
			Source:        source,
			OwnerID:       tool.OwnerID,
			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"

View on GitHub (pinned to 9f775e8a12)