MoveWithinRange was only moving the unit far enough away so the center of the target was above the minimum distance. However, the min range checks in the attack code require all positions on the target to be above the minimum distance. For large targets (e.g. buildings) this means some of the target was still too close, and the unit would get stuck in a loop.
Now MoveWithinRange uses the same range checks in order to ensure units are moved the correct distances.