{"record":{"id":"9f439d12b5af2b1f","repo":"siyuan-note/siyuan","slug":"unknown-tool-s","errorCode":null,"errorMessage":"unknown tool: %s","messagePattern":"unknown tool: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/agent/tools.go","lineNumber":42,"sourceCode":"\t\"strings\"\n\n\t\"github.com/sashabaranov/go-openai\"\n\t\"github.com/siyuan-note/siyuan/kernel/mcp/tools\"\n\tkernelModel \"github.com/siyuan-note/siyuan/kernel/model\"\n)\n\ntype executedToolResult struct {\n\tText             string\n\tModelAttachments []tools.ModelAttachment\n\tIsError          bool\n\tExecutionUnknown bool\n}\n\n// validateToolCallInput 在确认和快照之前校验工具调用，避免无效调用被误判为写操作。\nfunc validateToolCallInput(ctx context.Context, toolName string, args map[string]any) (*tools.Tool, *tools.ToolValidator, error) {\n\tt, validator := tools.LookupToolWithValidator(toolName)\n\tif t == nil {\n\t\treturn nil, nil, fmt.Errorf(\"unknown tool: %s\", toolName)\n\t}\n\tif t.ContextHandler == nil && t.Handler == nil {\n\t\treturn nil, nil, fmt.Errorf(\"tool handler unavailable: %s\", toolName)\n\t}\n\tif ctx.Err() != nil {\n\t\treturn nil, nil, fmt.Errorf(\"tool execution was cancelled before it started\")\n\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) {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/agent/tools.go#L24-L60","documentation":"validateToolCallInput looks up the requested tool by name with tools.LookupToolWithValidator. If no registered tool matches the name, it returns this error, so unrecognized tool names are rejected before confirmation and snapshot stages.","triggerScenarios":"Calling validateToolCallInput (via the agent chat/tool-call path) with a toolName that is not registered in the tools registry: typo, model hallucinating a tool name, or a tool removed/renamed in a newer version.","commonSituations":"LLM emits a tool call with a name from an old or imagined schema; plugin/tool not registered because its registration code did not run; case mismatch in tool name.","solutions":["Check the exact registered tool names exposed to the model and correct the caller/model prompt","Ensure the tool's registration function runs before the chat session starts","Log the available tool list when this error occurs to spot typos or case mismatches","If the model hallucinates names, tighten the tool schema/prompt describing available tools"],"exampleFix":"// before: assuming the tool exists\nvalidateToolCallInput(ctx, \"file_serach\", args)\n// after: verify against the registry first\nif _, ok := tools.Lookup(\"file_search\"); !ok {\n    return fmt.Errorf(\"tool %q is not registered\", \"file_search\")\n}\nvalidateToolCallInput(ctx, \"file_search\", args)","handlingStrategy":"validation","validationCode":"if t, _ := tools.LookupToolWithValidator(toolName); t == nil {\n    return fmt.Errorf(\"tool %q not registered; available: %v\", toolName, tools.Names())\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := validateToolCallInput(ctx, name, args); err != nil && strings.HasPrefix(err.Error(), \"unknown tool:\") {\n    return fmt.Errorf(\"model requested unregistered tool %q; check registry and prompt\", name)\n}","preventionTips":["Register all tools before starting a chat session","Keep the model's tool schema list in sync with the registry","Normalize tool name casing at the boundary"],"tags":["agent","tools","validation"],"backgroundTag":"unknown-tool","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"}