Headless Chrome will show you a mobile bug that isn't there
We were finishing a client demo site and took a quick mobile screenshot to confirm the layout:
chrome --headless --screenshot --window-size=390,844
The image came back clipped at the right edge. Classic horizontal overflow. So we did what you do: hunted for the too-wide element, questioned every margin, burned a full diagnosis cycle on a bug that did not exist. The page was fine. The screenshot was the bug.
What actually happens at 390 pixels
A bare headless window at 390px wide is still a desktop browser. No device metrics, no mobile user agent, and a wider minimum layout width than a phone uses. The page lays out for a desktop that happens to be narrow, overflows its own window, and the screenshot faithfully records a layout no phone will ever produce.
The measurement that settled it: we asked the page for its scrollWidth and got exactly 390. Nothing overflowed. Trust numbers over pictures when the two disagree.
The fix is device emulation, not a narrower window
Drive a real Chrome through puppeteer-core and set an actual device profile:
page.setViewport({ width: 390, height: 844, isMobile: true, hasTouch: true, deviceScaleFactor: 2 })
isMobile: true is the line doing the work. It switches the layout engine to phone behavior instead of squeezing a desktop. puppeteer-core uses the Chrome already on the machine, so there is no browser download. We keep 3 small scripts from that day: one that lists any element wider than the viewport, one for emulated screenshots, one for screenshots at scroll positions.
Two more ways screenshots lie
Full-page screenshot modes false-fail on pages with fixed video backgrounds or scroll animations. And any element that reveals on scroll will render invisible below the fold, because the screenshot captured its starting state, not a bug. Screenshot tools photograph one configuration of a page that has many.
Desktop-width shots from bare headless Chrome are still fine. It is only mobile that needs the real emulation. Now the rule at our shop is simple: no mobile verdict from a desktop engine, and when a picture and a measurement disagree, believe the measurement.