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

  1. Populate the Validator via tools.LookupToolWithValidator when building the registration (as executeTool does)
  2. Check the MCP server's tool definitions — provide an inputSchema so a validator can be constructed
  3. Audit all capabilityRegistration construction sites for the missing Validator field
  4. 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

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


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)