fix(lighthouse): resolve per-run TEMP to absolute — unbreaks all Web Vitals on Windows - #318
Conversation
Every Lighthouse measurement failed on Windows with "Unable to connect to Chrome", wiping out the entire vitals section of benchmark reports (8/8 measurements errored on a real farmrio run, all 3 retries each). measureLighthouseOnce builds a per-run temp dir and hands it to the spawned lighthouse process as TEMP/TMP. That dir descends from --output, which defaults to the RELATIVE "./parity-output", so TEMP was relative too. chrome-launcher feeds os.tmpdir() straight into Chrome's --user-data-dir, and Chrome cannot resolve a relative profile dir, so it dies during launch and chrome-launcher surfaces the misleading "Unable to connect to Chrome". Bisected by replicating the exact spawn() options and flipping only this path: relative -> no report + "Unable to connect to Chrome"; absolute -> report written. Shell, concurrency and Playwright contention were each ruled out as causes. Note this is easy to miss from a terminal: typing the same command in a shell exports TEMP through MSYS/cmd path normalization, which makes it absolute before Chrome ever sees it. Only the programmatic spawn preserves the relative form. Fixes lighthouse for every consumer (benchmark, vitals, checks), not just the benchmark path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Independent of the TEMP bug fixed in the previous commit: the benchmark ran its home/PLP/PDP Lighthouse passes through Promise.all, so each side had 3 Chrome instances measuring at once, both sides overlap, and Playwright still holds its own browsers open. Lighthouse measures CPU under a 4x throttle, so three concurrent passes inflate each other's LCP/TBT numbers. The vitals command already accounts for this, defaulting --lighthouse-concurrency to cores/2 capped at 2; the benchmark path never got the same treatment, which undercuts the prod-vs-cand comparison the report exists to make. Trades vitals-phase wall-clock for numbers that mean something. Applied to both journey shapes (commerce and content). Drop this commit if the speed matters more than the precision. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Verdict: COMMENT — the I verified the diagnosis rather than taking it on faith. From the failing run in
So Chrome spawned fine and wrote nothing — it discarded the relative
Worth fixing
Checked, fine
|
Problem
Every Lighthouse measurement fails on Windows with
Unable to connect to Chrome, so the entire Web Vitals section of benchmark reports comes back empty. On a realfarmriorun: 8/8 measurements errored, all 3 retries each, andreport.jsoncontained only{"error": "lighthouse exit 1: Unable to connect to Chrome"}for every page.Root cause
measureLighthouseOncebuilds a per-run temp dir and hands it to the spawnedlighthouseprocess asTEMP/TMP:outDirdescends from--output, which defaults to the relative./parity-output— soTEMPwas relative. chrome-launcher feedsos.tmpdir()straight into Chrome's--user-data-dir, and Chrome cannot resolve a relative profile dir. It dies during launch, and chrome-launcher surfaces the misleadingUnable to connect to Chrome— which points at connectivity, not at a path.How it was isolated
Replicated the exact
spawn()options in a standalone probe and flipped only the path form:runTempUnable to connect to Chrome, no reportRuled out along the way: shell (all runs were Git Bash), Lighthouse concurrency (3 concurrent standalone runs all succeeded), and Playwright contention (a standalone run succeeded while the benchmark's own Lighthouse was active).
Why this hides so well: running the same command from a terminal exports
TEMPthrough MSYS/cmd path normalization, which makes it absolute before Chrome ever sees it. Only the programmaticspawnpreserves the relative form — so it reproduces from the tool and never from the shell you'd debug it in.Changes
Two independent commits, reviewable separately:
157ee9cfix(lighthouse) — the actual bug.resolve()instead ofjoin()forrunTemp. Fixes Lighthouse for every consumer (benchmark,vitals,checks), not just the benchmark path.05de19dperf(benchmark) — independent measurement-validity issue found while debugging. The benchmark ran home/PLP/PDP throughPromise.all, so each side had 3 CPU-throttled Lighthouse passes measuring simultaneously, both sides overlapping, with Playwright's browsers still open. That inflates each other's LCP/TBT and undercuts the prod-vs-cand comparison the report exists to make. Thevitalscommand already accounts for this (--lighthouse-concurrencydefaults to cores/2 capped at 2); the benchmark path never got it. Costs vitals-phase wall-clock. Drop this commit if speed matters more than precision.Verification
tsc --noEmit)vi.stubGlobalissues, untouched by this changefarmriobenchmark on the fixed build:cand-mobile-home-a1.jsonwritten at 1.5MB on attempt a1 — first try, no retries. Same run pre-fix: 3 empty retry dirs, 0 reports.🤖 Generated with Claude Code
Summary by cubic
Fixes Windows Lighthouse failures by resolving the per-run TEMP/TMP directory to an absolute path, restoring Web Vitals. Also runs the three benchmark Lighthouse pages sequentially to avoid inflated metrics and launch failures.
--outputpath causedchrome-launcherto pass a relative--user-data-dirto Chrome, which failed to launch with "Unable to connect to Chrome" and produced empty reports. New: useresolve()to make the per-run temp path absolute.lighthousepath (benchmark,vitals,checks). No configuration changes or migrations required.Written for commit 05de19d. Summary will update on new commits.