#34704·cypress

cy.intercept response-header overrides are silently ignored on redirect responses in Chrome — Fetch.continueResponse does not apply them at the redirect-received pause

Author: AtofStrykerCreated Aug 27, 2026Updated Sep 17, 2026

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 develop build (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: encodePausedResponse computes fulfilled = false when the body digest is unchanged (packages/server/lib/browsers/cdp-protocol/cdp-fetch-codec.ts), and toContinuedHeaders includes the rewritten location and detects the change.
  • The transport then sends Fetch.continueResponse with responseHeaders containing the new location (cdp-fetch-transport.ts).
  • Redirect pauses are already special-cased for bodies (isRedirectPause — CDP refuses Fetch.getResponseBody in 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 a cy.intercept handler 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 statusMessage finding 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 continueResponse tracker #34352 and the proxy-disabled list #34276 have no redirect/location entries, and no issue matches redirect/location-override keywords.