In reconstruct_prepared_transactions_initial_sync.js, there is a race between the primary receiving the "commit transaction" instruction from the test for transaction four, and the primary receiving a heartbeat response or replSetUpdatePosition from the secondary notifying it that the secondary has applied the "prepare" instruction for that same transaction.
Currently, we "prepare" transaction four on the primary while the secondary is in initial sync. We then call "awaitSecondaryNodes" to ensure that the secondary has finished initial sync (and therefore applied the "prepare" oplog entry for transaction four) before committing the transaction. However, "awaitSecondaryNodes" does not guarantee that the primary has heard from the secondary that it has applied the "prepare" for the transaction, which would allow it to advance the majority commit point to or past the "prepare" entry. Thus, if the commit transaction request is received by the primary before the primary receives such an update from the secondary, then the majority commit point will still be behind the "prepare" entry for the transaction and we will hit this uassert.
We should add something like ReplSetTest.awaitLastOpCommitted before committing the transaction to ensure not only that the secondary has finished initial sync + applied the prepare op locally, but also that the primary is aware of this fact and can therefore advance the majority commit point.