without forceHttp1 the first `cy.visit()` hangs forever (no timeout) when the spec bundle is large
Current behavior
Since upgrading to Cypress 16.0.0, a spec whose bundle is large stalls forever at the first
cy.visit() of that spec. There is no error and no timeout: pageLoadTimeout is configured to
120 s and never fires, defaultCommandTimeout never fires either, and the browser process sits at
0.00 s CPU for as long as the run is left alive (verified across several minutes). The run has to be
killed. Setting forceHttp1: true makes the very same spec pass.
Context: our specs import a generated TypeScript API per clinical study. The biggest of those are
40–80 MB of sources, bundled by @cypress/webpack-preprocessor with swc-loader. The stall is a
pure function of that bundle size — with a 15 MB study API the spec passes, from about 40 MB upwards
it never returns.
We also see that the first cy.visit() of a spec reloads the AUT and re-runs the test body (visible
as duplicated output at the top of the test). That reload looks like where it dies: it has to
re-fetch the spec bundle, and on the native network path a large one apparently never arrives.
Desired behavior
Either the visit completes the way it did in Cypress 15, or at the very least the configured
pageLoadTimeout applies, so that a run fails with an error instead of hanging indefinitely. A
suite that stops producing output and burns no CPU is indistinguishable from a dead machine.
Test code to reproduce
- Write a spec that pulls in a large module graph (ours: about 40 MB of generated TypeScript,
bundled through
@cypress/webpack-preprocessorwithswc-loader). - Call
cy.visit()once in that spec. - Run
cypress run --browser chrome— the run stalls at the visit and never times out. - Re-run with
--config forceHttp1=true— it passes.
We have not reduced this to a public standalone reproduction yet. The trigger appears to be bundle size alone rather than anything specific to our code, so a spec importing a synthetic module of comparable size should show it. Happy to build one if that would help.
Cypress Version
16.0.0
Other
Measurements
All runs cypress run --browser chrome on the same machine, same spec body (a cy.visit() after a
few cookie/session commands), differing only in which study API the spec imports:
| imported study API (TS sources) | forceHttp1 |
result |
|---|---|---|
| 15 MB | off | passes; the AUT reload after the first visit takes 6.5 s |
| 40 MB | off | hangs forever (no timeout after 3+ min, 0 % CPU) |
| 51 MB (a different study, unrelated code) | off | hangs forever |
| 40 MB | on | passes; the AUT reload takes 12.4 s |
Ruled out by bisection:
- Not
manageBrowserMemory.--config manageBrowserMemory=falsestill hangs. (We hadexperimentalMemoryManagement: falsebefore the upgrade, so this was our first suspect.) - Not the preceding commands. The identical
cy.visit()in the identical command sequence passes in about 2 s as soon as the spec's study import is removed.
Versions
- Cypress: 16.0.0
- Browser: Chrome 152, headless
- Operating system: Windows 11 Enterprise 26200
- Node: 24.20.0
@cypress/webpack-preprocessor7.0.2,webpack5.104.1,@swc/core1.15.2
Relevant configuration: pageLoadTimeout: 120000, defaultCommandTimeout: 20000, video: false,
defaultBrowser: "chrome".
Filing this because the docs ask for it: forceHttp1 fixes our suite, and the difference we see is
not one of the documented behaviour changes.
Source: cypress-io/cypress