Seen mentioned a bad network connection can cause this, and it can, but the network connection is pristine best I can figure. Digging some more showed the device had just bytes left of free memory.
Luckily since I was running the web_server, managed to recover using curl. Couldn’t get it to send it’s web page to the browser, but it was still accepting POST requests so. Made a minimal config yaml with just basic boiler plate and network for updates and then uploaded it using this command:
curl -X POST -F update=@/home/netsplit/esphome/bathroom-switch.bin 'http://bathroom-switch.lan/update'
Then was able to resume updating it through OTA with a less ambitious build. Just posting this for anyone else having this issue.