siyuan-note/siyuan · error
capability validator unavailable
Error message
capability validator unavailable: %s
What it means
validateCapabilityCall requires registration.Validator to be non-nil; a registered capability without a ToolValidator cannot have its arguments schema-checked, so execution is refused. This is an internal consistency guard on the capability registration.
Solutions
- Populate the Validator via tools.LookupToolWithValidator when building the registration (as executeTool does)
- Check the MCP server's tool definitions — provide an inputSchema so a validator can be constructed
- Audit all capabilityRegistration construction sites for the missing Validator field
- Report/fix the internal path that registered a capability without a validator
Example fix
// before: registration without validator
reg := &capabilityRegistration{ID: id, Tool: tool}
// after: fetch validator alongside the tool
tool, validator := tools.LookupToolWithValidator(name)
reg := &capabilityRegistration{ID: id, Tool: tool, Validator: validator} Defensive patterns
Strategy: validation
Validate before calling
if reg.Validator == nil {
return executedToolResult{Text: "capability validator unavailable: " + reg.ID, IsError: true}
} Type guard
func hasValidator(r *capabilityRegistration) bool { return r != nil && r.Validator != nil } Prevention
- Construct registrations only via LookupToolWithValidator
- Audit all capabilityRegistration construction sites for Validator
- Require MCP tools to declare an inputSchema
When it happens
Trigger: A capabilityRegistration was constructed with Validator: nil — e.g. a custom/bridge path (not executeTool, which always populates Validator via LookupToolWithValidator) registering an MCP or browser capability without fetching its validator.
Common situations: Custom integrations registering capabilities directly, MCP servers that omit an input schema so no validator could be built, or code changes adding new registration paths that forget the validator.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- capability handler unavailable
- capability was not exposed in this model round
- invalid capability arguments
- tool arguments must be a JSON object
- AI editor action must not be empty
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/ede93300bff40373.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/agent/tools.go:67
}
if err := validator.ValidateInputContext(ctx, args); err != nil {
return nil, nil, fmt.Errorf("invalid tool arguments: %w", err)
}
return t, validator, nil
}
func validateCapabilityCall(ctx context.Context, registration *capabilityRegistration, args map[string]any) error {
if registration == nil {
return fmt.Errorf("capability was not exposed in this model round")
}
if !capabilityStillExecutable(registration, args) {
return fmt.Errorf("capability is disabled or no longer available: %s", registration.ID)
}
if ctx.Err() != nil {
return fmt.Errorf("capability execution was cancelled before it started")
}
if registration.Validator == nil {
return fmt.Errorf("capability validator unavailable: %s", registration.ID)
}
if err := registration.Validator.ValidateInputContext(ctx, args); err != nil {
return fmt.Errorf("invalid capability arguments: %w", err)
}
if !registration.isBrowser() &&
(registration.Tool == nil || registration.Tool.ContextHandler == nil && registration.Tool.Handler == nil) {
return fmt.Errorf("capability handler unavailable: %s", registration.ID)
}
return nil
}
// executeTool 执行单次工具调用。
func executeTool(ctx context.Context, tc openai.ToolCall, sessionID string) executedToolResult {
tool, validator := tools.LookupToolWithValidator(tc.Function.Name)
if tool == nil {
return executedToolResult{Text: "unknown tool: " + tc.Function.Name, IsError: true}
}
return executeCapability(ctx, tc, sessionID, &capabilityRegistration{View on GitHub (pinned to 9f775e8a12)