{"record":{"id":"ede93300bff40373","repo":"siyuan-note/siyuan","slug":"capability-validator-unavailable-s","errorCode":null,"errorMessage":"capability validator unavailable: %s","messagePattern":"capability validator unavailable: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/agent/tools.go","lineNumber":67,"sourceCode":"\t}\n\tif err := validator.ValidateInputContext(ctx, args); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"invalid tool arguments: %w\", err)\n\t}\n\treturn t, validator, nil\n}\n\nfunc validateCapabilityCall(ctx context.Context, registration *capabilityRegistration, args map[string]any) error {\n\tif registration == nil {\n\t\treturn fmt.Errorf(\"capability was not exposed in this model round\")\n\t}\n\tif !capabilityStillExecutable(registration, args) {\n\t\treturn fmt.Errorf(\"capability is disabled or no longer available: %s\", registration.ID)\n\t}\n\tif ctx.Err() != nil {\n\t\treturn fmt.Errorf(\"capability execution was cancelled before it started\")\n\t}\n\tif registration.Validator == nil {\n\t\treturn fmt.Errorf(\"capability validator unavailable: %s\", registration.ID)\n\t}\n\tif err := registration.Validator.ValidateInputContext(ctx, args); err != nil {\n\t\treturn fmt.Errorf(\"invalid capability arguments: %w\", err)\n\t}\n\tif !registration.isBrowser() &&\n\t\t(registration.Tool == nil || registration.Tool.ContextHandler == nil && registration.Tool.Handler == nil) {\n\t\treturn fmt.Errorf(\"capability handler unavailable: %s\", registration.ID)\n\t}\n\treturn nil\n}\n\n// executeTool 执行单次工具调用。\nfunc executeTool(ctx context.Context, tc openai.ToolCall, sessionID string) executedToolResult {\n\ttool, validator := tools.LookupToolWithValidator(tc.Function.Name)\n\tif tool == nil {\n\t\treturn executedToolResult{Text: \"unknown tool: \" + tc.Function.Name, IsError: true}\n\t}\n\treturn executeCapability(ctx, tc, sessionID, &capabilityRegistration{","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/agent/tools.go#L49-L85","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: registration without validator\nreg := &capabilityRegistration{ID: id, Tool: tool}\n// after: fetch validator alongside the tool\ntool, validator := tools.LookupToolWithValidator(name)\nreg := &capabilityRegistration{ID: id, Tool: tool, Validator: validator}","handlingStrategy":"validation","validationCode":"if reg.Validator == nil {\n    return executedToolResult{Text: \"capability validator unavailable: \" + reg.ID, IsError: true}\n}","typeGuard":"func hasValidator(r *capabilityRegistration) bool { return r != nil && r.Validator != nil }","tryCatchPattern":null,"preventionTips":["Construct registrations only via LookupToolWithValidator","Audit all capabilityRegistration construction sites for Validator","Require MCP tools to declare an inputSchema"],"tags":["ai","tool-calling","internal","validation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}