cy.intercept response-header overrides are silently ignored on redirect responses in Chrome — Fetch.continueResponse does not apply them at the redirect-received pause
Current behavior
On Cypress 16, rewriting a redirect's Location header in a cy.intercept response handler has no effect in Chrome/Chromium/Edge — the browser follows the origin's original Location. Cypress 15 applies the rewrite.
Repro is stubbing-spying__intercept/redirect-spec.cy.js in cypress-example-recipes ("stubs the redirect"): the handler rewrites res.headers.location from https://www.cypress.io to / and calls res.send(). On 16 in Chrome the browser navigates to www.cypress.io and the test fails on the cross-origin page. Verified:
- A/B in the same checkout: green on
[email protected], red on the 16 pre-release. - Reproduced on the current
developbuild (698d9692d3, 2026-08-27) — 1 of 2 tests failing across 6 attempts, server logs showing the original redirect followed every time. - Passes under Electron in recipes CI. The failure is silent: the override is dropped with no error.
Mechanism
The Cypress pipeline verifiably emits the override — the drop happens in the browser:
- A header-only change takes the continue path:
encodePausedResponsecomputesfulfilled = falsewhen the body digest is unchanged (packages/server/lib/browsers/cdp-protocol/cdp-fetch-codec.ts), andtoContinuedHeadersincludes the rewrittenlocationand detects the change. - The transport then sends
Fetch.continueResponsewithresponseHeaderscontaining the newlocation(cdp-fetch-transport.ts). - Redirect pauses are already special-cased for bodies (
isRedirectPause— CDP refusesFetch.getResponseBodyin the redirect-received state), but not for header overrides.
The observed behavior implies Chrome does not apply Fetch.continueResponse header overrides at the redirect-received pause. Fetch.fulfillRequest is the documented way to replace a redirect response.
Proposed fix shape
When a response pause is a redirect (isRedirectPause) and middleware changed headers, take the fulfill path instead of continue (a redirect's body is already the empty stand-in, so fulfilling with an empty body is faithful). Needs verification against Chrome that fulfill applies the rewritten Location, plus a check of the status-only-change case (req.reply changing a 302 to 200 on a redirect pause).
Acceptance criteria
- Rewriting
res.headers.location(and other headers) on a 3xx response in acy.intercepthandler takes effect in Chrome/Chromium/Edge on 16 — the browser follows the rewritten target - The recipes spec
stubbing-spying__intercept/redirect-spec.cy.js("stubs the redirect") passes on Chrome against a build containing the fix - Non-redirect header-only overrides keep taking
continueResponse(no regression to the fulfill-vs-continue policy for mimeType/Test Replay) - Unit coverage in the codec/transport specs for the redirect-with-changed-headers path
- Electron/Firefox/WebKit behavior unchanged
Scope notes
- Found via the Cypress 16 bump in cypress-io/cypress-example-recipes#938; discussion of the companion
statusMessagefinding lives in #34656 / #34703 (fixed by #34665). - There is no CI coverage for this path today: the intercept recipe has no Chrome job in recipes CI, and it passes under Electron.
- Searched for prior reports before filing: the
continueResponsetracker #34352 and the proxy-disabled list #34276 have no redirect/location entries, and no issue matches redirect/location-override keywords.
Source: cypress-io/cypress