I managed to find a way to reliably reproduce this issue. The way to do it is to unplug the board while Serial Monitor is open. That does it every time.
I plug my Arduino boards into a USB hub that's seen better days, so it's possible that I sometimes get a momentary loss of USB connectivity if I jiggle the cable or bang my work bench, which could have been causing the same thing to be happening even when I didn't intentionally unplug the cable.
I found that the duplicate Tools > Port menu entries issue didn't occur when using the beta build of the Arduino IDE, but that the spurious upload error still did occur with that IDE version. The issue does not occur with Arduino IDE 1.8.8.
I opened a bug report in the Arduino IDE repository about this: https://github.com/arduino/Arduino/issues/8851