{"record":{"id":"ff00eea37dbb4c74","repo":"Tencent/WeKnora","slug":"tool-name-is-required","errorCode":null,"errorMessage":"tool_name is required","messagePattern":"tool_name is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/mcp_tool_approval_service.go","lineNumber":39,"sourceCode":"\treturn &mcpToolApprovalService{repo: repo, mcpRepo: mcpRepo}\n}\n\nfunc (s *mcpToolApprovalService) ListByService(ctx context.Context, tenantID uint64, serviceID string) ([]*types.MCPToolApproval, error) {\n\tsvc, err := s.mcpRepo.GetByID(ctx, tenantID, serviceID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif svc == nil {\n\t\treturn nil, fmt.Errorf(\"mcp service not found\")\n\t}\n\treturn s.repo.ListByService(ctx, tenantID, serviceID)\n}\n\nfunc (s *mcpToolApprovalService) SetRequireApproval(\n\tctx context.Context, tenantID uint64, serviceID, toolName string, require bool,\n) error {\n\tif toolName == \"\" {\n\t\treturn fmt.Errorf(\"tool_name is required\")\n\t}\n\tsvc, err := s.mcpRepo.GetByID(ctx, tenantID, serviceID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif svc == nil {\n\t\treturn fmt.Errorf(\"mcp service not found\")\n\t}\n\trow := &types.MCPToolApproval{\n\t\tTenantID:        tenantID,\n\t\tServiceID:       serviceID,\n\t\tToolName:        toolName,\n\t\tRequireApproval: require,\n\t}\n\treturn s.repo.Upsert(ctx, row)\n}\n\nfunc (s *mcpToolApprovalService) IsRequired(ctx context.Context, tenantID uint64, serviceID, toolName string) (bool, error) {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/mcp_tool_approval_service.go#L21-L57","documentation":"Argument validation at the top of SetRequireApproval: the toolName parameter is empty, so there is no tool whose approval requirement could be toggled. It fires before any service or approval lookup, indicating the caller omitted the tool_name from the request.","triggerScenarios":"Calling SetRequireApproval with toolName=\"\" (empty string literal, unset struct field, or request body missing tool_name).","commonSituations":"Client deserialization omits tool_name when the JSON field is absent; binding an empty form field; passing a variable that was never populated from tool metadata.","solutions":["Supply the exact tool name from the MCP service's tool list","Validate tool_name is non-empty in the HTTP handler before calling the service","Check that the request struct field maps the correct JSON key (tool_name)","Default the UI/API to send the wildcard or per-tool name the approval system expects"],"exampleFix":"// before\nerr := approvalSvc.SetRequireApproval(ctx, tenantID, serviceID, toolName, true)\n// after\nif toolName == \"\" {\n\treturn errors.New(\"tool_name is required\")\n}\nerr := approvalSvc.SetRequireApproval(ctx, tenantID, serviceID, toolName, true)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(req.ToolName) == \"\" {\n\treturn http.StatusBadRequest // or a typed validation error\n}\nerr := approvalSvc.SetRequireApproval(ctx, tenantID, serviceID, req.ToolName, req.Require)","typeGuard":null,"tryCatchPattern":"err := approvalSvc.SetRequireApproval(ctx, tenantID, serviceID, toolName, require)\nif err != nil && strings.Contains(err.Error(), \"tool_name is required\") {\n\treturn ErrMissingToolName // 400 Bad Request\n}","preventionTips":["Make tool_name required in request schemas/DTOs with explicit validation tags","Derive tool names from the MCP service's tool metadata, not free-form input","Trim whitespace before sending","Cover the empty-toolName case in handler tests"],"tags":["validation","mcp","missing-parameter"],"backgroundTag":"missing-required-argument","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}