This is one of the problems that I have encountered many times.
The installation contains one or more merge modules. Installation works absolutely fine if fresh install is performed. But if previous installation is upgraded using major upgrade, merge module files are not installed. I have also encountered this issue with .NET assemblies to be installed in GAC. After performing the install, if you repair the product, merge modules/ .NET assemblies are installed.
The cause is placement of RemoveExistingProducts action after CostFinalize action. What really happens is that Costting process sees that the files are already installed, it marks those components not to be installed again. Its a mystery that why it happens for few files only. After costing is complete, RemoveExistingProducts action uninstalls the old product including .NET assemblies/ merge modules. Now when new install is performed, those components are marked not be installed, so final result is that those files are missing. When repair is performed, install will see those files missing, so those files will be put back again.
Solution is really very simple. Just move the RemoveExistingProducts action in Execute sequence before CostInitialize action. Thats it.