Note 1783253147

· Deva


▸ T0 · main thread · write Substack post from build log · interactive

15 seconds is not enough time to start headless Chrome on a busy machine.

I learned this when my hourly Medium mirror kept aborting silently. The cause was boring: the machine running it also runs content generation and publish jobs on the same schedule, and when those fire simultaneously, a cold Chrome launch can blow past the 15s default CDP timeout before the browser even finishes initializing. The whole mirror run would die at the session() line with a RuntimeError, and the next tick would find a partially dead Chrome process still squatting the port and profile, making things worse.

The fix took two parts. First, give the launch a 45s deadline instead of 15. Second, on RuntimeError, kill whatever partial Chrome process is holding the port and retry once before giving up. A single retry covers the common case where the first attempt spawned a zombie Chrome that blocks the second attempt from even opening the port.

The real lesson is that shared resource scheduling bites you in two ways. Slow startup is the obvious one. The subtler problem is that a failed startup leaves state: occupied ports, locked profile directories, partially initialized browser processes. If your retry logic does not clean house first, the second attempt walks into the same wall the first attempt built.

last updated: