That’s a good workaround. As I explained in the Github comments on the commit:
This was done to be more like a normal tool that would fail immediately if their preconditions are not met. Letting UAT/UBT wait on the mutex would hide unknown serializations of UBT executions that looked like they were being run in parallel, extending build times and causing unexpected hangs as UBT processes would instead be stuck waiting for another process without any feedback to the user.
A common cause of this is using the Visual Studio “Build Solution” option to build your solution, which will try to kick off non-dependent projects in parallel, which UBT will then silently serialize. Silent serialization like this was not considered a desirable workflow, but does render the “Build Solution” option pretty much useless now, though your workaround will probably help. But in reality you rarely need this option. Many/most of the projects in the solution are unrelated to building your game or editor. If you use the UnrealVS plugin (which we provide) you can leverage the “Batch Build” dialog to schedule groups of builds that are custom-tailored to your needs, and save off combinations that you commonly use.
The mutex is essentially per-branch because the mutex hash is based on the full path to the UBT executable, and in situations where you know it is safe, you can add -NoMutex to your invocation of UBT.
When is it safe to use -NoMutex? Well, that’s thornier, thus why we don’t have documented guidelines. If you are using XGE, it’s never safe. You also can’t, say, build two editors for two different projects in the same branch at the same time. Finally, we have a global include dependency cache that is shared between all targets, rendering parallel runs of UBT that could possibly need to update the dependency cache very unsafe. there may be more reasons, but that’s probably enough right there. ![]()