By adding a missing sync_blocks call.
There was a race at node2 between connecting the block produced by node0, and using -generate to create new blocks itself. In the failed run, block generation started before connecting the block, resulting in a final block height that was smaller by 1 than expected.
See #29392 (comment) for a more detailed analysis of the failed run.
Can be reproduced by adding a sleep to this spot  in ChainstateManager::ProcessNewBlock():
0if (util::ThreadGetInternalName() == "msghand") {
1    std::this_thread::sleep_for(0.2s);
2}
which fails for me on master and succeeds with the fix.
Fixes #29392